denoland/deno · error
app name {app_name:?} resolves its runtime library to {runti
Error message
app name {app_name:?} resolves its runtime library to {runtime_name}, which is the launcher itself. Choose a different --output name. What it means
When packaging a desktop (laufey) app, `resolve_app_dir_targets` derives both the runtime library name and the launcher name from the app name. On Linux the colocated runtime name is computed by stripping the extension from the app name and appending `.so`; for an app name like `myapp.so` this truncates back to exactly the launcher file name, so the runtime library would overwrite the launcher itself. The check at cli/tools/desktop.rs:3105 detects this identity and bails, telling you to pick a different `--output` name.
Source
Thrown at cli/tools/desktop.rs:3106
/// `fs::copy` and `fs::rename` both replace silently, so every check has to run
/// before either does. Returning the paths only on success is what keeps that
/// ordering intact: a caller cannot reach the paths without having passed the
/// checks, so a later refactor can't reorder them apart.
fn resolve_app_dir_targets(
app_dir: &Path,
app_name: &str,
runtime_name: &str,
launcher_name: &str,
laufey_binary_name: &str,
) -> Result<AppDirTargets, AnyError> {
validate_launcher_name(app_name, "app name")?;
let dest_dylib = app_dir.join(runtime_name);
let launcher_path = app_dir.join(launcher_name);
let staged_backend = app_dir.join(laufey_binary_name);
reject_backend_file_collision(&dest_dylib, app_name, "runtime library")?;
if dest_dylib == launcher_path {
bail!(
"app name {app_name:?} resolves its runtime library to {runtime_name}, \
which is the launcher itself. Choose a different --output name.",
);
}
// The staged backend is the file we are about to rename *into* the launcher
// path, so it colliding with itself is the normal case, not a clash.
if launcher_path != staged_backend {
reject_backend_file_collision(&launcher_path, app_name, "launcher")?;
}
Ok(AppDirTargets {
dest_dylib,
launcher_path,
staged_backend,
})
}
/// Refuse an app-derived file name that lands on a file the backend shipped.
///View on GitHub (pinned to f7822238ca)
Solutions
- Pick a `--output` name that does not end in `.so` (e.g. `--output myapp` instead of `--output myapp.so`), so the runtime library `myapp.so` differs from the launcher
- If the `.so` suffix is added by a build script, remove the suffix before invoking the desktop packager
- If the name must keep the suffix, place the output in a different app layout or file the tooling to support alternative runtime-library naming
Example fix
// before deno compile --desktop --output myapp.so main.ts // after deno compile --desktop --output myapp main.ts
Defensive patterns
Strategy: validation
Validate before calling
fn launcher_and_runtime_collide(app_name: &str) -> bool {
let base = match app_name.rfind('.') {
Some(dot) if dot > 0 => &app_name[..dot],
_ => app_name,
};
// runtime library is `{base}.so`; the launcher keeps the full app name
format!("{base}.so") == app_name
}
if launcher_and_runtime_collide(output_name) {
eprintln!("--output {output_name} collides with its own runtime library; drop the .so suffix");
std::process::exit(2);
} Type guard
fn safe_desktop_output_name(name: &str) -> bool {
!name.ends_with(".so") && !name.is_empty()
} Try / catch
match resolve_app_dir_targets(app_dir, app_name, runtime_name, launcher_name, laufey_binary_name) {
Ok(targets) => /* proceed with packaging */,
Err(e) if e.to_string().contains("which is the launcher itself") => {
eprintln!("choose an --output name without the .so suffix");
std::process::exit(2);
}
Err(e) => return Err(e),
} Prevention
- On Linux, never pass an `--output` name ending in `.so` to desktop packaging
- Review CI/build scripts that append `.so` or other extensions to output names before packaging
- Dry-run the name derivation (strip extension, append `.so`) and compare against the launcher name before packaging
- Keep app output names simple (no extension) and let the packager derive the runtime-library name
When it happens
Trigger: Running `deno compile --desktop` (app packaging) with `--output myapp.so` (or any name whose extension-stripped base plus `.so` equals the launcher name) on Linux, so `dest_dylib == launcher_path`.
Common situations: Choosing an `.so`-suffixed `--output` name on Linux because the artifact happens to be a shared library; build scripts that append `.so` to the output name; renaming outputs in CI without re-checking desktop packaging constraints.
Related errors
- No bundled AppImage runtime for arch '{other}'; supported: x
- No Debian architecture mapping for arch '{other}'; supported
- No RPM architecture mapping for arch '{other}'; supported: x
- no .desktop file found in {}
- deno.json `version` "{version}" cannot be used as a Debian/R
AI-assisted analysis of denoland/deno@f7822238ca (2026-08-29).
Data as JSON: /api/errors/b6d21729f8785b6d.
Report an issue: GitHub.