-
-
Notifications
You must be signed in to change notification settings - Fork 33.8k
Closed
Labels
fsIssues and PRs related to the fs subsystem / file system.Issues and PRs related to the fs subsystem / file system.
Description
Version
v24.1.0
Platform
Linux Laptop-16-AMD-Ryzen-7040-Series 6.8.0-60-generic #63-Ubuntu SMP PREEMPT_DYNAMIC Tue Apr 15 19:04:15 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Subsystem
fs
What steps will reproduce the bug?
Run the following code:
"use strict";
const fs = require("node:fs");
const path = require("node:path");
// cleans up test and dest directories
fs.rmSync("./tmp/test", { recursive: true, force: true });
fs.rmSync("./tmp/dest", { recursive: true, force: true });
// prepares the test directory
fs.mkdirSync("./tmp/test", { recursive: true });
// in the test directory creates a source.txt file and a link.txt symlink that points to the source.txt file
fs.writeFileSync("./tmp/test/source.txt", "test content");
fs.symlinkSync(path.resolve("./tmp/test/source.txt"),"./tmp/test/link.txt");
// call cpSync
fs.cpSync("./tmp/test", "./tmp/dest", { recursive: true });
// call cpSync again (this so with dest already existing/populated)
fs.cpSync("./tmp/test", "./tmp/dest", { recursive: true });How often does it reproduce? Is there a required condition?
the issue can always be reproduced and it does not require a specific condition
What is the expected behavior? Why is that the expected behavior?
I believe that the second cpSync call should not throw any error, but the existing symlink files should be skipped unless force is set to false and errorOnExist is true, in such case an EEXIST error should be thrown instead
What do you see instead?
The second cpSync call throws an ERR_FS_CP_EINVAL error
Additional information
-
The
ERR_FS_CP_EINVALerror is thrown even whenforceis being used (and the dest file is not overridden). -
This applies both to
cpandcpSync`cp` reproduction
"use strict"; const fs = require("node:fs"); const path = require("node:path"); fs.rmSync("./tmp/test", { recursive: true, force: true }); fs.rmSync("./tmp/dest", { recursive: true, force: true }); fs.mkdirSync("./tmp/test", { recursive: true }); fs.writeFileSync("./tmp/test/source.txt", "test content"); fs.symlinkSync(path.resolve("./tmp/test/source.txt"),"./tmp/test/link.txt"); fs.cp("./tmp/test", "./tmp/dest", { recursive: true }, (err) => { if(err) throw err; fs.cp("./tmp/test", "./tmp/dest", { recursive: true }, (err) => { if (err) throw err; }); });
- setting
dereferencetotrueseems to fix the issue, however I am not sure if dereferencing is actually taking place since the symlinks are copied as such and not as the files they point to (which I think is the expected behavior? π€)
idango10
Metadata
Metadata
Assignees
Labels
fsIssues and PRs related to the fs subsystem / file system.Issues and PRs related to the fs subsystem / file system.