From 696a6ea6838aab863cf9badeed5e6082ce71d232 Mon Sep 17 00:00:00 2001 From: Daijiro Wachi Date: Thu, 25 Jun 2026 18:13:17 +0900 Subject: [PATCH] fs: throw on existing dir in cpSync with errorOnExist cpSync() did not honor errorOnExist when the destination directory already existed, while the asynchronous cp() does (fixed in the commit that added test-fs-cp-async-dir-exists-error-on-exist). Mirror that guard in the synchronous onDir() so both APIs behave identically. Signed-off-by: Daijiro Wachi --- lib/internal/fs/cp/cp-sync.js | 9 ++++++ ...t-fs-cp-sync-dir-exists-error-on-exist.mjs | 32 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 test/parallel/test-fs-cp-sync-dir-exists-error-on-exist.mjs diff --git a/lib/internal/fs/cp/cp-sync.js b/lib/internal/fs/cp/cp-sync.js index 03fcae9b7cdbda..1769ef50b97109 100644 --- a/lib/internal/fs/cp/cp-sync.js +++ b/lib/internal/fs/cp/cp-sync.js @@ -134,6 +134,15 @@ function setDestTimestamps(src, dest) { // TODO(@anonrig): Move this function to C++. function onDir(srcStat, destStat, src, dest, opts) { if (!destStat) return copyDir(src, dest, opts, true, srcStat.mode); + if (opts.errorOnExist && !opts.force) { + throw new ERR_FS_CP_EEXIST({ + message: `${dest} already exists`, + path: dest, + syscall: 'cp', + errno: EEXIST, + code: 'EEXIST', + }); + } return copyDir(src, dest, opts); } diff --git a/test/parallel/test-fs-cp-sync-dir-exists-error-on-exist.mjs b/test/parallel/test-fs-cp-sync-dir-exists-error-on-exist.mjs new file mode 100644 index 00000000000000..bcc95476a9f655 --- /dev/null +++ b/test/parallel/test-fs-cp-sync-dir-exists-error-on-exist.mjs @@ -0,0 +1,32 @@ +// This tests that cpSync() throws if errorOnExist is true, force is false, +// and the destination directory already exists (even if contents don't +// conflict), matching the asynchronous cp() behavior. + +import '../common/index.mjs'; +import { nextdir } from '../common/fs.js'; +import assert from 'node:assert'; +import { cpSync, mkdirSync, writeFileSync } from 'node:fs'; +import tmpdir from '../common/tmpdir.js'; + +tmpdir.refresh(); + +const src = nextdir(); +const dest = nextdir(); + +// Create source directory with a file +mkdirSync(src); +writeFileSync(`${src}/file.txt`, 'test'); + +// Create destination directory with a different (non-conflicting) file +mkdirSync(dest); +writeFileSync(`${dest}/other.txt`, 'existing'); + +// Should throw because dest directory already exists +assert.throws( + () => cpSync(src, dest, { + recursive: true, + errorOnExist: true, + force: false, + }), + { code: 'ERR_FS_CP_EEXIST' }, +);