denoland/deno · error · SystemError
ERR_FS_CP_EEXIST
ERR_FS_CP_EEXIST
Error message
Target already exists
What it means
When fs.cp copies a file onto an existing destination, the native code consults the force and errorOnExist options (and the COPYFILE_EXCL mode): with force:false and errorOnExist:true (or an exclusive copy mode), an existing dest is rejected with kind EEXIST, mapped by throwCpError to ERR_FS_CP_EEXIST ('Target already exists', errno EEXIST). Without errorOnExist the copy would silently skip; this flag turns the skip into an explicit error.
Solutions
- If overwriting is fine, set force: true (with errorOnExist removed/false) so dest is unlinked before the copy
- If the conflict is real, catch the error and surface which path already exists (err.path)
- Pre-check with fs.existsSync(dest) and branch to skip/overwrite explicitly instead of relying on the throw
Example fix
// before
fs.cp('app.tar', '/srv/app.tar', { errorOnExist: true }, cb); // dest exists
// after — allow overwrite
fs.cp('app.tar', '/srv/app.tar', { force: true }, cb);
// after — deliberate conflict handling
if (fs.existsSync('/srv/app.tar')) { /* skip or ask */ } else fs.cp('app.tar', '/srv/app.tar', cb); Defensive patterns
Strategy: try-catch
Validate before calling
if (opts.errorOnExist && fs.existsSync(dest)) { /* decide explicitly instead of letting cp throw */ } Try / catch
try { await fs.promises.cp(src, dest, { errorOnExist: true, force: false }); } catch (e) { if (e.code === 'ERR_FS_CP_EEXIST') return { skipped: true, existing: e.path }; throw e; } Prevention
- errorOnExist only bites with force:false — set force:true when overwrite is intended
- Pre-check existence when the not-clobber guarantee matters
- Log e.path so operators see which target collided
When it happens
Trigger: fs.cp(src, dest, { errorOnExist: true, force: false }, cb) with dest present; copying with fs.constants.COPYFILE_EXCL semantics where the dest already exists; CI pipelines asserting 'first deploy wins' by failing on any pre-existing artifact.
Common situations: Atomic installers that must not clobber a previous release; concurrent workers racing to create the same output file; re-running a generator that treats an existing output as a conflict instead of an overwrite.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/4b9114d3985fa25a.
Report an issue: GitHub.
Appendix: source
Thrown at ext/node/polyfills/_fs/cp/cp.ts:84
});
case "DIR_TO_NON_DIR":
throw new ERR_FS_CP_DIR_TO_NON_DIR({
message: err.message,
path: err.path,
syscall: "cp",
errno: EISDIR,
code: "EISDIR",
});
case "NON_DIR_TO_DIR":
throw new ERR_FS_CP_NON_DIR_TO_DIR({
message: err.message,
path: err.path,
syscall: "cp",
errno: ENOTDIR,
code: "ENOTDIR",
});
case "EEXIST":
throw new ERR_FS_CP_EEXIST({
message: err.message,
path: err.path,
syscall: "cp",
errno: EEXIST,
code: "EEXIST",
});
case "EISDIR":
throw new ERR_FS_EISDIR({
message: err.message,
path: err.path,
syscall: "cp",
errno: EISDIR,
code: "EISDIR",
});
case "SOCKET":
throw new ERR_FS_CP_SOCKET({
message: err.message,
path: err.path,View on GitHub (pinned to 9ad36f7a2c)