denoland/deno · error
No valid icon images found for .icns
Error message
No valid icon images found for .icns
What it means
The .icns builder iterates configured icon entries: files that don't exist are skipped with a warning, and sizes that don't map to a standard macOS iconset slot (only 16/32/64/128/256/512/1024 are recognized by icns_ostypes_for_size) contribute no OSType and are also skipped with a warning. If no entry survives — none of the files exist, or all sizes are non-standard — the build bails.
Solutions
- Fix the icon paths so each resolves relative to the cwd you run `deno desktop` from.
- Use only standard iconset sizes: 16, 32, 64, 128, 256, 512, 1024.
- Watch the preceding 'Icon ... not found, skipping' and "doesn't map to a standard macOS iconset slot" warnings — they say exactly which entries dropped out.
- Make sure at least one icon file is committed/exists on the build machine.
Example fix
// before: wrong relative root + non-standard size
"icons": [{ "path": "./assets/icons/logo_48.png", "size": 48 }]
// after
"icons": [{ "path": "assets/icons/logo_256.png", "size": 256 }] Defensive patterns
Strategy: validation
Validate before calling
// Validate icon config before building (paths are cwd-relative; sizes must be iconset slots)
const ICONSET_SIZES = new Set([16, 32, 64, 128, 256, 512, 1024]);
for (const icon of config.desktop.icons) {
if (!ICONSET_SIZES.has(icon.size)) throw new Error(`size ${icon.size} is not a standard iconset slot`);
if (!existsSync(icon.path)) throw new Error(`icon not found: ${icon.path}`);
} Type guard
function isStandardIconsetSize(n: number): boolean {
return [16, 32, 64, 128, 256, 512, 1024].includes(n);
} Prevention
- Always provide at least the 512 (or 1024) slot for macOS builds.
- Resolve icon paths from the project cwd in scripts; document that they are not config-file-relative.
- Commit icon assets so CI sees the same files as local builds.
When it happens
Trigger: All icon paths in the desktop config resolve to nonexistent files (paths are joined against the project cwd, so wrong relative paths are the usual cause), or every configured size is unsupported (48, 0, 999...), so icons ends up empty even though files exist.
Common situations: Icons declared relative to the config file instead of the working directory; sizes like 48 or 20 picked by hand; icon files excluded from git so only CI fails.
Related errors
- macos.codesignIdentity is empty
- No valid icon images found for .ico
- app bundle has no name
- bundle identifier has an empty segment
- bundle identifier is longer than 155 characters
AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20).
Data as JSON: /api/errors/12929de5b309e830.
Report an issue: GitHub.
Appendix: source
Thrown at cli/tools/desktop.rs:5536
icns_path: &Path,
) -> Result<(), deno_core::error::AnyError> {
use std::io::Write;
let mut icons: Vec<(&'static [u8; 4], 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)?;
for code in icns_ostypes_for_size(entry.size) {
icons.push((*code, data.clone()));
}
}
if icons.is_empty() {
deno_core::anyhow::bail!("No valid icon images found for .icns");
}
// File header (8 bytes) + for each icon: 4-byte OSType + 4-byte length + payload.
let total_size: u32 = icons
.iter()
.map(|(_, data)| 8 + data.len() as u32)
.sum::<u32>()
+ 8;
let mut buf = Vec::with_capacity(total_size as usize);
buf.write_all(b"icns")?;
buf.write_all(&total_size.to_be_bytes())?;
for (code, data) in &icons {
buf.write_all(*code)?;
let entry_len = 8 + data.len() as u32;
buf.write_all(&entry_len.to_be_bytes())?;
buf.write_all(data)?;
}View on GitHub (pinned to f7822238ca)