Skip to content

Inconsistency in fs.cp operation #58947

Description

@jasnell

In the fs.cp... API, we have options such as errorOnExist and force that are intended to control what happens when the destination already exists. There is, however, a discrepancy in how the options are implemented depending on whether the src/dest are files or directories.

For instance, let's suppose we have the following directory layout:

~/tmp
| -- ~/tmp/a (file)
| -- ~/tmp/b (file)
| -- ~/tmp/c (directory)
| | -- /tmp/c/1 (file)
| -- ~/tmp/d (directory)
| -- /tmp/d/2 (file)

Then, in the fs.cp operation, let's first try copying a to b, with options errorOnExist: true and force: false we get the appropriate error indicating that the destination exists and we're not going to overwrite it:

>fs.cp('a','b',{errorOnExist: true,force: false},console.log)undefined>SystemError[ERR_FS_CP_EEXIST]: Targetalreadyexists: cpreturnedEEXIST(balreadyexists)batmayCopyFile(node:internal/fs/cp/cp:250:11)atonFile(node:internal/fs/cp/cp:242:10)atgetStatsForCopy(node:internal/fs/cp/cp:211:12){code: 'ERR_FS_CP_EEXIST',info: {message: 'b already exists',path: 'b',syscall: 'cp',errno: 17,code: 'EEXIST'},errno: [Getter/Setter: 17],syscall: [Getter/Setter: 'cp'],path: [Getter/Setter: 'b']}

However, if we try copying c to d, with options errorOnExist: true and force: false, we happily go ahead and copy contents of 'c' over to 'd', erroring only if one of the individual files in d overlaps with a file in c

>fs.cp('c','d',{recursive: true,errorOnExist: true,force: false},console.log)undefined>nullundefined

This just feels wrong. d already exists and we're being told not to force. I would expect the behavior to be the same as copying the files. If d exists, this operation should fail.

I don't think we can change this behavior now without it being semver-major and potentially breaking a lot of things but we really ought to have an option of enforcing that no copy is performed if d exists.

@nodejs/fs @anonrig@dario-piotrowicz

Metadata

Metadata

Assignees

No one assigned

    Labels

    fsIssues and PRs related to the fs subsystem / file system.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions