bmad-code-org/BMAD-METHOD · error · Error
${dest} already exists
Error message
${dest} already exists What it means
Thrown by the native fs copy() helper when overwrite is false, options.errorOnExist is true, and the destination file already exists. This mirrors fs-extra semantics: a non-overwriting copy that is configured to error (rather than silently skip) refuses to clobber an existing file.
Source
Thrown at tools/installer/fs-native.js:36
await fsp.mkdir(dir, { recursive: true });
}
async function remove(p) {
await fsp.rm(p, { recursive: true, force: true });
}
async function copy(src, dest, options = {}) {
const filterFn = options.filter;
const overwrite = options.overwrite !== false;
const srcStat = await fsp.stat(src);
if (srcStat.isFile()) {
if (filterFn && !(await filterFn(src, dest))) return;
await fsp.mkdir(path.dirname(dest), { recursive: true });
if (!overwrite) {
try {
await fsp.access(dest);
if (options.errorOnExist) throw new Error(`${dest} already exists`);
return;
} catch (error) {
if (error.message.includes('already exists')) throw error;
}
}
await fsp.copyFile(src, dest);
return;
}
if (srcStat.isDirectory()) {
if (filterFn && !(await filterFn(src, dest))) return;
await fsp.mkdir(dest, { recursive: true });
const entries = await fsp.readdir(src, { withFileTypes: true });
for (const entry of entries) {
await copy(path.join(src, entry.name), path.join(dest, entry.name), options);
}
}
}View on GitHub (pinned to b70486b9bd)
Solutions
- Delete or move the existing destination before copying.
- Pass overwrite:true if clobbering is acceptable.
- Pass errorOnExist:false to silently skip existing files instead of throwing.
Example fix
// before
await fs.copy(src, dest, { overwrite: false, errorOnExist: true });
// after (allow overwrite)
await fs.copy(src, dest, { overwrite: true }); Defensive patterns
Strategy: validation
Validate before calling
if (options.errorOnExist && !(options.overwrite ?? true) && (await fs.pathExists(dest))) {
// remove dest first, or switch off errorOnExist
} Try / catch
try {
await fs.copy(src, dest, { overwrite: false, errorOnExist: true });
} catch (error) {
if (error.message.endsWith('already exists')) { /* dest collision; handle */ }
throw error;
} Prevention
- Only set errorOnExist when you genuinely want collisions to fail.
- Clean the destination tree before non-overwriting copies.
When it happens
Trigger: fs.copy(src, dest, { overwrite: false, errorOnExist: true }) and `dest` already exists. The default FileOps.copyDirectory sets errorOnExist:false, so this only fires when a caller explicitly opts into errorOnExist.
Common situations: A caller intentionally requests fail-on-exist semantics (e.g. to detect collisions) and the destination path is already present from a prior run.
Related errors
- ${label} does not exist: ${dirPath}
- ${label} is not a directory: ${dirPath}
- ${label} is not readable: ${dirPath}
- ${label} does not exist: ${filePath}
- ${label} is not a file: ${filePath}
AI-assisted analysis of bmad-code-org/BMAD-METHOD@b70486b9bd (2026-08-13).
Data as JSON: /api/errors/24ceb49df05fda75.
Report an issue: GitHub.