denoland/deno · error

Refusing to overwrite '{}': a file with that name already ex

Error message

Refusing to overwrite '{}': a file with that name already exists. Pass --output to choose a different name.

What it means

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.

Source

Thrown at cli/tools/desktop.rs:1528

/// Prepare `app_dir` to receive a freshly built bundle.
///
/// The app name is inferred from the entrypoint (or, for generic names like
/// `main.ts`, the project directory), so the output path can collide with an
/// existing user directory of the same name (e.g. `helloworld/helloworld`).
/// Blindly `remove_dir_all`-ing that path silently destroys the user's data
/// (issue #35510). Instead, only remove a directory we previously created —
/// identified by `APP_DIR_MARKER` — or one that is empty. Anything else is
/// treated as user data and we bail with instructions rather than delete it.
fn reserve_app_dir(app_dir: &Path) -> Result<(), AnyError> {
  let meta = match std::fs::symlink_metadata(app_dir) {
    // Nothing there yet (or unreadable) — let the build create it.
    Err(_) => return Ok(()),
    Ok(meta) => meta,
  };

  if !meta.is_dir() {
    bail!(
      "Refusing to overwrite '{}': a file with that name already exists. \
       Pass --output to choose a different name.",
      app_dir.display()
    );
  }

  // A bundle we generated carries the marker (at the directory root for
  // Linux/Windows, or under `Contents/Resources` for a macOS `.app`).
  let is_ours = app_dir.join(APP_DIR_MARKER).exists()
    || app_dir
      .join("Contents")
      .join("Resources")
      .join(APP_DIR_MARKER)
      .exists();
  let is_empty = std::fs::read_dir(app_dir)
    .map(|mut entries| entries.next().is_none())
    .unwrap_or(false);

View on GitHub (pinned to f7822238ca)

Solutions

  1. Pass `--output` with a fresh name/path: `deno desktop --output dist/MyApp-dbg main.ts`.
  2. Or move/delete the colliding file yourself after confirming it is disposable.
  3. Rename the entrypoint or project dir so the inferred app name no longer collides.

Example fix

# before (a file named MyApp already exists)
$ ls
MyApp  main.ts
deno desktop main.ts

# after
deno desktop --output dist/MyAppDesktop main.ts
Defensive patterns

Strategy: validation

Validate before calling

# bash: ensure the output path is not an existing file
OUT="dist/MyApp"
if [[ -f "$OUT" ]]; then echo "refusing: $OUT is a file" >&2; exit 1; fi
deno desktop --output "$OUT" main.ts

Prevention

When it happens

Trigger: `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.

Common situations: 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.

Related errors


AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20). Data as JSON: /api/errors/e4d93f3a9fd2db90. Report an issue: GitHub.