{"record":{"id":"3f2ed634389f0472","repo":"denoland/deno","slug":"app-name-app-name-resolves-its-kind-to-name","errorCode":null,"errorMessage":"app name {app_name:?} resolves its {kind} to {name}, which is already part of the app. Choose a different --output name.","messagePattern":"app name (.+?) resolves its (.+?) to (.+?), which is already part of the app\\. Choose a different --output name\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/tools/desktop.rs","lineNumber":3140,"sourceCode":"\n/// Refuse an app-derived file name that lands on a file the backend shipped.\n///\n/// The app dir starts life as a copy of the LAUFEY backend directory, so it\n/// already holds the backend's own files — `libcef.so` and friends on Linux,\n/// `libcef.dll` / `d3dcompiler_47.dll` / the helper executables on Windows.\n/// Both the runtime library and the launcher are named after the app, so an app\n/// name that resolves onto one of those would overwrite it (`fs::copy` and\n/// `fs::rename` both replace silently) and ship an app that can't start.\nfn reject_backend_file_collision(\n  path: &Path,\n  app_name: &str,\n  kind: &str,\n) -> Result<(), AnyError> {\n  if !path.exists() {\n    return Ok(());\n  }\n  let name = path.file_name().unwrap_or_default().to_string_lossy();\n  bail!(\n    \"app name {app_name:?} resolves its {kind} to {name}, which is already \\\n     part of the app. Choose a different --output name.\",\n  );\n}\n\n/// The runtime dylib filename each macOS LAUFEY backend resolves when the\n/// backend binary is the bundle's CFBundleExecutable (i.e. no `--runtime`\n/// argument is passed). The two macOS backends use different conventions:\n/// - `webview` searches a hardcoded `libruntime.dylib` via [NSBundle mainBundle]\n///   (laufey `webview/src/main_mac.mm`).\n/// - `cef` derives `<backend-executable-basename>.dylib` next to the binary\n///   (laufey `LaufeyFindColocatedRuntime`, `cef/src/runtime_loader.cc`).\nfn macos_runtime_dylib_name(backend: &str, laufey_exe_stem: &str) -> String {\n  if backend == \"cef\" {\n    format!(\"{laufey_exe_stem}.dylib\")\n  } else {\n    \"libruntime.dylib\".to_string()\n  }","sourceCodeStart":3122,"sourceCodeEnd":3158,"githubUrl":"https://github.com/denoland/deno/blob/f7822238cab635a3a19f99f493f675fa81a7f9d8/cli/tools/desktop.rs#L3122-L3158","documentation":"This error is thrown by `reject_backend_file_collision` in cli/tools/desktop.rs when a backend file that the app builder needs to write (e.g. a launcher binary or runtime dylib for a given `--output` name) already exists at the target path. Since that existing file is already 'part of the app', overwriting it would corrupt the bundle, so the tool refuses and asks for a different --output name. It is a deliberate safety guard against name collisions inside the generated desktop app layout.","triggerScenarios":"Calling the desktop app build with an `--output` name such that the resolved path for one of the backends' files (identified by `kind`) already exists, e.g. the output name equals an existing file of the app bundle (a previously generated binary, dylib, or other backend artifact). The check only fires when `path.exists()` is true.","commonSituations":"Re-running a build with an --output name that matches a file inside the app bundle rather than the bundle itself; choosing an --output name identical to an internal backend artifact (like a dylib or helper binary); migrating build configs where the output directory now contains leftover files from a previous run whose names collide.","solutions":["Pick a different `--output` name that does not resolve to an existing file in the app bundle.","Delete or move the colliding file at the resolved path if it is stale output from a previous build.","Build into a fresh/clean output directory so no pre-existing files match backend filenames."],"exampleFix":"// before\ndeno desktop build --output myapp   # myapp already exists as a backend file in the bundle\n// after\ndeno desktop build --output myapp-desktop  # or delete the stale 'myapp' file first","handlingStrategy":"validation","validationCode":"import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n// Before building, ensure the --output name won't collide with existing app files\nif (existsSync(join(outputDir, outputName))) {\n  throw new Error(`--output name \"${outputName}\" already exists in the app dir; pick another`);\n}","typeGuard":"function isFreeOutputName(dir: string, name: string): boolean {\n  return !existsSync(join(dir, name));\n}","tryCatchPattern":"try {\n  await buildDesktopApp({ output: outputName });\n} catch (err) {\n  if (String(err.message).includes(\"already part of the app\")) {\n    console.error(`Output name \"${outputName}\" collides with an app file; choose a different --output name.`);\n  } else {\n    throw err;\n  }\n}","preventionTips":["Always build desktop apps into a clean, dedicated output directory.","Pick --output names distinct from any internal bundle artifacts (binaries, dylibs, helpers).","Clean stale build outputs between runs instead of reusing names."],"tags":["cli","desktop","name-collision","file-conflict"],"backgroundTag":"output-file-name-collision","analyzedSha":"f7822238cab635a3a19f99f493f675fa81a7f9d8","analyzedAt":"2026-08-29T08:55:39.519Z","contentChangedAt":"2026-08-29T08:55:39.519Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}