denoland/deno · error · NodeSystemError
ERR_FS_CP_NON_DIR_TO_DIR
ERR_FS_CP_NON_DIR_TO_DIR
Error message
Cannot overwrite directory with non-directory
What it means
ERR_FS_CP_NON_DIR_TO_DIR is the mirror case of DIR_TO_NON_DIR: the source is a non-directory (file, symlink to file) while the existing destination is a directory. Writing the file would clobber the directory, so fs.cp/fsp.cp rejects it via throwCpError kind 'NON_DIR_TO_DIR' with errno ENOTDIR-style code.
Source
Thrown at ext/node/polyfills/_fs/cp/cp.ts:76
switch (err.kind) {
case "EINVAL":
throw new ERR_FS_CP_EINVAL({
message: err.message,
path: err.path,
syscall: "cp",
errno: EINVAL,
code: "EINVAL",
});
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,View on GitHub (pinned to 89f33cbef2)
Solutions
- Target the file inside the directory: path.join(destDir, path.basename(src))
- Or remove the destination directory if it should be replaced by the file
- Pre-stat both paths and branch on the combination (file->file, dir->dir) before copying
Example fix
// before
await fsp.cp('bundle.js', 'dist'); // dist is an existing directory
// after
await fsp.cp('bundle.js', path.join('dist', 'bundle.js')); Defensive patterns
Strategy: validation
Validate before calling
const destStat = await fsp.lstat(dest).catch(() => null); const target = destStat?.isDirectory() ? path.join(dest, path.basename(src)) : dest; await fsp.cp(src, target);
Type guard
async function isDir(p) { try { return (await fsp.lstat(p)).isDirectory(); } catch { return false; } } Try / catch
try { await fsp.cp(src, dest); } catch (e) { if (e.code === 'ERR_FS_CP_NON_DIR_TO_DIR') throw new Error(`dest ${dest} is a directory; use path.join(dest, basename(src))`); throw e; } Prevention
- When copying into a folder, always join(dest, basename(src))
- Document whether each path variable is a file or a directory
- Pre-stat both endpoints in copy utilities and branch
When it happens
Trigger: await fsp.cp('./bundle.js', './dist') where ./dist is an existing directory; fs.cpSync('config.json', 'settings/') with settings/ a directory.
Common situations: Forgetting that a path is created as a directory by an earlier step (mkdir -p); copying a single artifact into a folder while naming the folder itself as dest instead of folder/name.
Related errors
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/6c7a79dd289a7a15.
Report an issue: GitHub.