denoland/deno · error

icon ' ' not found

Error message

icon '{}' not found

What it means

Thrown by resolve_hmr_icon_path (macOS only) when the configured single icon path, resolved by joining it with the initial working directory, does not exist on disk before the HMR app launches. The check is a plain `Path::exists`, so anything — typo, wrong cwd assumption, missing file — trips it.

Solutions

  1. Check the file exists: `ls -l <path-from-error-message>` — the error prints the joined absolute path it tried.
  2. Run `deno desktop --hmr` from the directory the relative icon path is written against, or make the icon path absolute in the config.
  3. Restore/regenerate the icon file (it may be gitignored or removed) and fix casing to match the filesystem exactly.

Example fix

# before (run from repo root, but icon is under ./assets)
deno desktop --hmr --icon app-icon.icns main.ts

# after
deno desktop --hmr --icon assets/app-icon.icns main.ts
Defensive patterns

Strategy: validation

Validate before calling

# bash: check the icon resolves before launching
ICON="assets/AppIcon.icns"
[[ -f "$ICON" ]] || { echo "missing icon: $ICON" >&2; exit 1; }
deno desktop --hmr --icon "$ICON" main.ts

Prevention

When it happens

Trigger: `deno desktop --hmr --icon icons/app.png` run from a directory other than the project root when the path is relative; icon file renamed or deleted after config was written; case-sensitivity mismatch on macOS filesystems after copying from Linux/Windows; absolute path pointing at an unmounted volume.

Common situations: Relative icon path in config but the command is launched from a subdirectory or via an IDE task with a different cwd; git checkout where .icns/.png is gitignored so teammates lack the file; path copied with a trailing space or smart quotes from docs/chat.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at cli/tools/desktop.rs:1169

}

/// Resolve `icon` (a `.png` or `.icns` path, possibly relative to
/// `initial_cwd`) into an absolute path suitable for `LAUFEY_APP_ICON`, which
/// laufey passes to `-[NSImage initWithContentsOfFile:]` (both formats are
/// accepted, so no conversion is needed).
#[cfg(target_os = "macos")]
fn resolve_hmr_icon_path(
  icon: &crate::args::IconConfig,
  initial_cwd: &Path,
) -> Result<PathBuf, AnyError> {
  let icon_path = match icon {
    crate::args::IconConfig::Single(p) => initial_cwd.join(p),
    crate::args::IconConfig::Set(_) => {
      deno_core::anyhow::bail!("icon sets are not supported in --hmr mode yet")
    }
  };
  if !icon_path.exists() {
    deno_core::anyhow::bail!("icon '{}' not found", icon_path.display());
  }
  match icon_path.extension().and_then(|e| e.to_str()) {
    Some("icns") | Some("png") => {}
    _ => deno_core::anyhow::bail!(
      "icon '{}' must be .icns or .png",
      icon_path.display()
    ),
  }
  Ok(crate::util::fs::canonicalize_path(&icon_path).unwrap_or(icon_path))
}

/// Extract the local URL from a line of dev server output.
fn parse_dev_server_url(line: &str) -> Option<String> {
  let line = console_static_text::ansi::strip_ansi_codes(line);
  // Vite prints `  ➜  Local:   http://localhost:5173/`
  regex::Regex::new(r"Local:\s+(https?://\S+)")
    .expect("regex to parse local url failed")
    .captures(&line)

View on GitHub (pinned to f7822238ca)