denoland/deno · error

No valid icon images found for .ico

Error message

No valid icon images found for .ico

What it means

The .ico builder iterates configured icon entries and skips files that don't exist (with a warning); unlike the .icns path, every size is accepted into the ICO directory since ICO stores arbitrary PNG entries. It bails only when no configured icon file could be read at all — i.e. the images list ended up empty.

Solutions

  1. Correct the icon paths so they resolve from the directory where `deno desktop` runs.
  2. Confirm the icon files are committed/present on the build machine (`ls` each configured path).
  3. Keep at least one existing PNG entry in the icons list.

Example fix

// before
"icons": [{ "path": "icons/logo_256.png", "size": 256 }]
// (fails because the folder is actually assets/icons)

// after
"icons": [{ "path": "assets/icons/logo_256.png", "size": 256 }]
Defensive patterns

Strategy: validation

Validate before calling

for icon in $(jq -r '.desktop.icons[].path' deno.json); do
  [ -f "$icon" ] || { echo "icon missing: $icon"; exit 1; }
done

Prevention

When it happens

Trigger: Every icon path in the desktop config points at a nonexistent file (paths are resolved by joining with the cwd), or the icon list is effectively empty after skips. A single existing, readable file is enough to pass.

Common situations: Icon paths written relative to the config file rather than the invocation directory; icons gitignored so CI can't see them; moved/renamed asset folders.

Related errors


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

Appendix: source

Thrown at cli/tools/desktop.rs:5606

  cwd: &Path,
  entries: &[crate::args::IconSetEntry],
  ico_path: &Path,
) -> Result<(), deno_core::error::AnyError> {
  use std::io::Write;

  let mut images: Vec<(u32, Vec<u8>)> = Vec::new();
  for entry in entries {
    let src = cwd.join(&entry.path);
    if !src.exists() {
      log::warn!("Icon '{}' not found, skipping", src.display());
      continue;
    }
    let data = std::fs::read(&src)?;
    images.push((entry.size, data));
  }

  if images.is_empty() {
    deno_core::anyhow::bail!("No valid icon images found for .ico");
  }

  let count = images.len() as u16;
  // ICO header: 6 bytes
  // Each directory entry: 16 bytes
  let header_size = 6 + (count as u32) * 16;

  let mut buf = Vec::new();
  // ICO header
  buf.write_all(&0u16.to_le_bytes())?; // reserved
  buf.write_all(&1u16.to_le_bytes())?; // type: 1 = ICO
  buf.write_all(&count.to_le_bytes())?; // image count

  // Directory entries
  let mut data_offset = header_size;
  for (size, data) in &images {
    // Width/height: 0 means 256 in ICO format
    let dim = if *size >= 256 { 0u8 } else { *size as u8 };

View on GitHub (pinned to f7822238ca)