{"record":{"id":"7bd67d692f2bfb5f","repo":"remix-run/react-router","slug":"file-collisions-detected-in-a-non-interactive-envi","errorCode":null,"errorMessage":"File collisions detected in a non-interactive environment","messagePattern":"File collisions detected in a non-interactive environment","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/create-react-router/index.ts","lineNumber":393,"sourceCode":"        lines.push(`and ${moreFiles} more...`);\n      }\n      return lines.join(`\\n${prefix}`);\n    };\n\n    if (ctx.overwrite) {\n      info(\n        \"Overwrite:\",\n        `overwriting files due to \\`--overwrite\\`:${getFileList(\"           \")}`,\n      );\n    } else if (!ctx.interactive) {\n      error(\n        \"Oh no!\",\n        `Destination directory contains files that would be overwritten\\n` +\n          `         and no \\`--overwrite\\` flag was included in a non-interactive\\n` +\n          `         environment. The following files would be overwritten:` +\n          getFileList(\"           \"),\n      );\n      throw new Error(\n        \"File collisions detected in a non-interactive environment\",\n      );\n    } else {\n      if (ctx.debug) {\n        debug(`Colliding files:${getFileList(\"          \")}`);\n      }\n\n      let { overwrite } = await ctx.prompt({\n        name: \"overwrite\",\n        type: \"confirm\",\n        label: title(\"overwrite\"),\n        message:\n          `Your project directory contains files that will be overwritten by\\n` +\n          `             this template (you can force with \\`--overwrite\\`)\\n\\n` +\n          `             Files that would be overwritten:` +\n          `${getFileList(\"               \")}\\n\\n` +\n          `             Do you wish to continue?\\n` +\n          `             `,","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/remix-run/react-router/blob/6beaca39526d5716c3c112ebb0782765baa5a9ce/packages/create-react-router/index.ts#L375-L411","documentation":"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.","triggerScenarios":"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.","commonSituations":"Rerunning a partially failed CI scaffold; initializing into a folder that already has files; caching the target directory between CI runs.","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"],"exampleFix":"# before (non-interactive, dir not empty)\nnpx create-react-router ./existing-dir --yes\n\n# after: explicit overwrite, or a fresh directory\nnpx create-react-router ./existing-dir --yes --overwrite\n# or\nnpx create-react-router ./fresh-dir --yes","handlingStrategy":"validation","validationCode":"import { existsSync, readdirSync } from \"node:fs\";\n\nfunction targetIsSafe(dir: string): boolean {\n  // Non-interactive runs require an empty (or absent) target unless --overwrite is passed\n  return !existsSync(dir) || readdirSync(dir).length === 0;\n}\n\nconst args = targetIsSafe(projectDir) ? baseArgs : [...baseArgs, \"--overwrite\"];","typeGuard":null,"tryCatchPattern":"try {\n  await createReactRouter(args);\n} catch (e) {\n  if ((e as Error).message === \"File collisions detected in a non-interactive environment\") {\n    console.error(\"Target not empty — rerun with --overwrite or use a fresh directory\");\n    process.exit(1);\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["cli","filesystem","ci","overwrite"],"backgroundTag":"file-already-exists","analyzedSha":"6beaca39526d5716c3c112ebb0782765baa5a9ce","analyzedAt":"2026-08-18T18:04:14.938Z","contentChangedAt":"2026-08-18T18:04:14.938Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}