remix-run/react-router · error · Error
File collisions detected in a non-interactive environment
Error message
File collisions detected in a non-interactive environment
What it means
copyTempDirToAppDirStep() compares the template file list with the destination directory; when files collide, an interactive shell gets a confirm prompt, but a non-interactive run (no TTY, --yes implied) must abort unless --overwrite was passed. This error is that abort — the colliding file names are printed in the error output above the throw.
Solutions
- Scaffold into a new or empty directory
- Add --overwrite to intentionally replace the colliding files
- Remove or move the files listed in the error output, then re-run
Example fix
# before (non-interactive, dir not empty) npx create-react-router ./existing-dir --yes # after: explicit overwrite, or a fresh directory npx create-react-router ./existing-dir --yes --overwrite # or npx create-react-router ./fresh-dir --yes
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync, readdirSync } from "node:fs";
function targetIsSafe(dir: string): boolean {
// Non-interactive runs require an empty (or absent) target unless --overwrite is passed
return !existsSync(dir) || readdirSync(dir).length === 0;
}
const args = targetIsSafe(projectDir) ? baseArgs : [...baseArgs, "--overwrite"]; Try / catch
try {
await createReactRouter(args);
} catch (e) {
if ((e as Error).message === "File collisions detected in a non-interactive environment") {
console.error("Target not empty — rerun with --overwrite or use a fresh directory");
process.exit(1);
}
throw e;
} Prevention
- Scaffold into a freshly generated directory (mktemp -d) in CI
- Decide explicitly: either add --overwrite or clean the directory first — never rely on prompts when non-interactive
- Cache dependencies, not scaffolded project directories, between CI runs
When it happens
Trigger: Scaffolding into a non-empty directory from CI/Docker where isInteractive() is false; re-running a scaffold step into a directory that already contains template files (README, .gitignore, package.json); no --overwrite flag included.
Common situations: Rerunning a partially failed CI scaffold; initializing into a folder that already has files; caching the target directory between CI runs.
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
- Exiting to avoid overwriting files
- No project directory provided
- The provided template is not a valid local directory or…
- " " is an invalid template. Run to see supported template…
- File watcher error
AI-assisted analysis of remix-run/react-router@6beaca3952 (2026-08-18).
Data as JSON: /api/errors/7bd67d692f2bfb5f.
Report an issue: GitHub.
Appendix: source
Thrown at packages/create-react-router/index.ts:393
lines.push(`and ${moreFiles} more...`);
}
return lines.join(`\n${prefix}`);
};
if (ctx.overwrite) {
info(
"Overwrite:",
`overwriting files due to \`--overwrite\`:${getFileList(" ")}`,
);
} else if (!ctx.interactive) {
error(
"Oh no!",
`Destination directory contains files that would be overwritten\n` +
` and no \`--overwrite\` flag was included in a non-interactive\n` +
` environment. The following files would be overwritten:` +
getFileList(" "),
);
throw new Error(
"File collisions detected in a non-interactive environment",
);
} else {
if (ctx.debug) {
debug(`Colliding files:${getFileList(" ")}`);
}
let { overwrite } = await ctx.prompt({
name: "overwrite",
type: "confirm",
label: title("overwrite"),
message:
`Your project directory contains files that will be overwritten by\n` +
` this template (you can force with \`--overwrite\`)\n\n` +
` Files that would be overwritten:` +
`${getFileList(" ")}\n\n` +
` Do you wish to continue?\n` +
` `,View on GitHub (pinned to 6beaca3952)