{"record":{"id":"dc9719696c6f4b93","repo":"denoland/deno","slug":"no-valid-icon-images-found-for-ico","errorCode":null,"errorMessage":"No valid icon images found for .ico","messagePattern":"No valid icon images found for \\.ico","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/tools/desktop.rs","lineNumber":5606,"sourceCode":"  cwd: &Path,\n  entries: &[crate::args::IconSetEntry],\n  ico_path: &Path,\n) -> Result<(), deno_core::error::AnyError> {\n  use std::io::Write;\n\n  let mut images: Vec<(u32, Vec<u8>)> = Vec::new();\n  for entry in entries {\n    let src = cwd.join(&entry.path);\n    if !src.exists() {\n      log::warn!(\"Icon '{}' not found, skipping\", src.display());\n      continue;\n    }\n    let data = std::fs::read(&src)?;\n    images.push((entry.size, data));\n  }\n\n  if images.is_empty() {\n    deno_core::anyhow::bail!(\"No valid icon images found for .ico\");\n  }\n\n  let count = images.len() as u16;\n  // ICO header: 6 bytes\n  // Each directory entry: 16 bytes\n  let header_size = 6 + (count as u32) * 16;\n\n  let mut buf = Vec::new();\n  // ICO header\n  buf.write_all(&0u16.to_le_bytes())?; // reserved\n  buf.write_all(&1u16.to_le_bytes())?; // type: 1 = ICO\n  buf.write_all(&count.to_le_bytes())?; // image count\n\n  // Directory entries\n  let mut data_offset = header_size;\n  for (size, data) in &images {\n    // Width/height: 0 means 256 in ICO format\n    let dim = if *size >= 256 { 0u8 } else { *size as u8 };","sourceCodeStart":5588,"sourceCodeEnd":5624,"githubUrl":"https://github.com/denoland/deno/blob/f7822238cab635a3a19f99f493f675fa81a7f9d8/cli/tools/desktop.rs#L5588-L5624","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Correct the icon paths so they resolve from the directory where `deno desktop` runs.","Confirm the icon files are committed/present on the build machine (`ls` each configured path).","Keep at least one existing PNG entry in the icons list."],"exampleFix":"// before\n\"icons\": [{ \"path\": \"icons/logo_256.png\", \"size\": 256 }]\n// (fails because the folder is actually assets/icons)\n\n// after\n\"icons\": [{ \"path\": \"assets/icons/logo_256.png\", \"size\": 256 }]","handlingStrategy":"validation","validationCode":"for icon in $(jq -r '.desktop.icons[].path' deno.json); do\n  [ -f \"$icon\" ] || { echo \"icon missing: $icon\"; exit 1; }\ndone","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep at least one existing PNG icon entry for Windows builds; any size works for .ico, existence is what matters.","Don't gitignore icon assets that the packaging config references.","Re-check icon paths after moving asset folders."],"tags":["desktop","windows","icons","ico","config"],"backgroundTag":"missing-icon-resource","analyzedSha":"f7822238cab635a3a19f99f493f675fa81a7f9d8","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}