denoland/deno · error
no .desktop file found in
Error message
no .desktop file found in {} What it means
While registering deep links for a compiled desktop app on Linux, Deno scans the app bundle for a `.desktop` entry file to add `x-scheme-handler/<scheme>` MIME types and an `Exec=... %u` field code. If no `*.desktop` file exists in the bundle directory, registration aborts with this error.
Solutions
- Rebuild the desktop bundle with the current deno version so the `.desktop` entry is generated
- If you customize packaging, ensure a valid `<App>.desktop` file lands in the bundle root before deep-link registration
- List the bundle directory — the `.desktop` file should sit alongside the executable
Defensive patterns
Strategy: validation
Validate before calling
// Pre-check the bundle before registering deep links
const bundleDir = "./dist/myapp";
const hasDesktopEntry = [...Deno.readDirSync(bundleDir)].some((e) =>
e.name.endsWith(".desktop")
);
if (!hasDesktopEntry) {
throw new Error("bundle has no .desktop file — rebuild before registering schemes");
} Prevention
- Register deep links only against freshly built bundles
- Don't hand-modify build outputs before registration
- Keep packaging steps from renaming or dropping the .desktop file
When it happens
Trigger: Deep-link registration (schemes declared in the desktop configuration) run against a bundle directory that contains no `.desktop` file — the bundle was built without the desktop packaging step, or the directory was assembled or modified by hand.
Common situations: Older or custom-built bundles; artifacts copied piecemeal out of the build output; packaging steps that renamed or deleted the `.desktop` file before registration.
Related errors
- app name resolves its runtime library to , which is the…
- deno.json `version` " " cannot be used as a Debian/RPM…
- deno.json `version` " " cannot be used as a Debian/RPM…
- No bundled AppImage runtime for arch
- No Debian architecture mapping for arch
AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20).
Data as JSON: /api/errors/dd0d5449ccd2850b.
Report an issue: GitHub.
Appendix: source
Thrown at cli/tools/desktop.rs:821
plist::Value::Array(vec![plist::Value::Dictionary(url_type)]),
);
plist::to_file_xml(&plist_path, &dict)
.with_context(|| format!("failed to write {}", plist_path.display()))?;
Ok(())
}
/// Linux: add `x-scheme-handler/<scheme>` MIME types to the `.desktop` entry
/// and make sure `Exec=` forwards the opened URL via the `%u` field code.
fn register_deep_links_linux(
bundle_path: &Path,
schemes: &[String],
) -> Result<(), AnyError> {
let desktop_file = std::fs::read_dir(bundle_path)?
.filter_map(|e| e.ok().map(|e| e.path()))
.find(|p| p.extension().is_some_and(|e| e == "desktop"))
.ok_or_else(|| {
deno_core::anyhow::anyhow!(
"no .desktop file found in {}",
bundle_path.display()
)
})?;
let contents = std::fs::read_to_string(&desktop_file)?;
let mime = schemes
.iter()
.map(|s| format!("x-scheme-handler/{s};"))
.collect::<String>();
let mut out = String::with_capacity(contents.len() + mime.len() + 16);
let mut wrote_mime = false;
for line in contents.lines() {
if let Some(rest) = line.strip_prefix("Exec=") {
// The launcher must receive the URL as an argument, so ensure a `%u`
// field code is present exactly once.
if rest.contains("%u") || rest.contains("%U") {View on GitHub (pinned to f7822238ca)