{"record":{"id":"e4d93f3a9fd2db90","repo":"denoland/deno","slug":"refusing-to-overwrite-a-file-with-that-name","errorCode":null,"errorMessage":"Refusing to overwrite '{}': a file with that name already exists. Pass --output to choose a different name.","messagePattern":"Refusing to overwrite '(.+?)': a file with that name already exists\\. Pass --output to choose a different name\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/tools/desktop.rs","lineNumber":1528,"sourceCode":"\n/// Prepare `app_dir` to receive a freshly built bundle.\n///\n/// The app name is inferred from the entrypoint (or, for generic names like\n/// `main.ts`, the project directory), so the output path can collide with an\n/// existing user directory of the same name (e.g. `helloworld/helloworld`).\n/// Blindly `remove_dir_all`-ing that path silently destroys the user's data\n/// (issue #35510). Instead, only remove a directory we previously created —\n/// identified by `APP_DIR_MARKER` — or one that is empty. Anything else is\n/// treated as user data and we bail with instructions rather than delete it.\nfn reserve_app_dir(app_dir: &Path) -> Result<(), AnyError> {\n  let meta = match std::fs::symlink_metadata(app_dir) {\n    // Nothing there yet (or unreadable) — let the build create it.\n    Err(_) => return Ok(()),\n    Ok(meta) => meta,\n  };\n\n  if !meta.is_dir() {\n    bail!(\n      \"Refusing to overwrite '{}': a file with that name already exists. \\\n       Pass --output to choose a different name.\",\n      app_dir.display()\n    );\n  }\n\n  // A bundle we generated carries the marker (at the directory root for\n  // Linux/Windows, or under `Contents/Resources` for a macOS `.app`).\n  let is_ours = app_dir.join(APP_DIR_MARKER).exists()\n    || app_dir\n      .join(\"Contents\")\n      .join(\"Resources\")\n      .join(APP_DIR_MARKER)\n      .exists();\n  let is_empty = std::fs::read_dir(app_dir)\n    .map(|mut entries| entries.next().is_none())\n    .unwrap_or(false);\n","sourceCodeStart":1510,"sourceCodeEnd":1546,"githubUrl":"https://github.com/denoland/deno/blob/f7822238cab635a3a19f99f493f675fa81a7f9d8/cli/tools/desktop.rs#L1510-L1546","documentation":"Thrown by reserve_app_dir before a desktop build writes its output: the destination app directory/bundle path (from the inferred app name or --output) already exists as a FILE (symlink_metadata says not a directory). The tool refuses to overwrite or delete a user file, so it bails and asks you to pick another name. This guard exists because issue #35510 showed blindly clearing the path destroys user data.","triggerScenarios":"`deno desktop main.ts` where the inferred app name (entrypoint stem or project dir name) collides with an existing file like a sibling `./MyApp` file, or `--output dist/MyApp` where `dist/MyApp` is a regular file; a previous partial run left a file where a directory is expected.","commonSituations":"Project directory named `app` while a file `app` (script, zip, tarball) exists next to the entrypoint; --output pointing at a former zip artifact; shell completion or a previous command having created a placeholder file at the target path.","solutions":["Pass `--output` with a fresh name/path: `deno desktop --output dist/MyApp-dbg main.ts`.","Or move/delete the colliding file yourself after confirming it is disposable.","Rename the entrypoint or project dir so the inferred app name no longer collides."],"exampleFix":"# before (a file named MyApp already exists)\n$ ls\nMyApp  main.ts\ndeno desktop main.ts\n\n# after\ndeno desktop --output dist/MyAppDesktop main.ts","handlingStrategy":"validation","validationCode":"# bash: ensure the output path is not an existing file\nOUT=\"dist/MyApp\"\nif [[ -f \"$OUT\" ]]; then echo \"refusing: $OUT is a file\" >&2; exit 1; fi\ndeno desktop --output \"$OUT\" main.ts","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Give `--output` an explicit, tool-specific path instead of relying on the inferred app name.","Keep build outputs in a dedicated dist/ directory your sources never share a name with.","Check for name collisions between the entrypoint stem and sibling files."],"tags":["desktop","output-path","file-collision","data-safety","cli"],"backgroundTag":"output-path-collision","analyzedSha":"f7822238cab635a3a19f99f493f675fa81a7f9d8","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}