denoland/deno · error
CFBundleIdentifier is empty in {}
Error message
CFBundleIdentifier is empty in {} What it means
The plutil extraction succeeded (exit 0) but produced an empty string, so read_bundle_identifier rejects it. The Info.plist has a CFBundleIdentifier key whose value is empty — syntactically valid plist, semantically invalid identifier. Downstream codesigning and CEF helper prefix matching need a concrete id.
Source
Thrown at cli/tools/desktop.rs:2696
let output = std::process::Command::new("plutil")
.arg("-extract")
.arg("CFBundleIdentifier")
.arg("raw")
.arg("-o")
.arg("-")
.arg(&plist)
.output()
.context("failed to invoke plutil(1) to read CFBundleIdentifier")?;
if !output.status.success() {
bail!(
"plutil could not read CFBundleIdentifier from {}: {}",
plist.display(),
String::from_utf8_lossy(&output.stderr).trim(),
);
}
let id = String::from_utf8_lossy(&output.stdout).trim().to_string();
if id.is_empty() {
bail!("CFBundleIdentifier is empty in {}", plist.display());
}
Ok(id)
}
/// Cheap Mach-O sniff: a Mach-O file starts with one of the well-known
/// magic numbers (32-bit, 64-bit, fat — both endians). Used to skip
/// non-binaries inside `Contents/MacOS/` (shell launchers, update
/// sentinels) before passing them to `codesign(1)`, which would reject
/// them and abort the signing pass.
fn is_macho_file(path: &Path) -> bool {
let Ok(mut f) = std::fs::File::open(path) else {
return false;
};
use std::io::Read;
let mut magic = [0u8; 4];
if f.read_exact(&mut magic).is_err() {
return false;
}View on GitHub (pinned to f7822238ca)
Solutions
- Set a non-empty reverse-DNS value for CFBundleIdentifier in the bundle's Contents/Info.plist, e.g. com.acme.app.
- If the plist is generated during bundling, fix the upstream config that feeds the identifier so it isn't empty.
- Delete the staged bundle and rebuild so the plist is regenerated from valid config.
Example fix
<!-- before --> <key>CFBundleIdentifier</key> <string></string> <!-- after --> <key>CFBundleIdentifier</key> <string>com.acme.app</string>
Defensive patterns
Strategy: validation
Validate before calling
id=$(plutil -extract CFBundleIdentifier raw -o - "$APP/Contents/Info.plist" 2>/dev/null)
[ -n "$id" ] || { echo "CFBundleIdentifier missing/empty"; exit 1; } Prevention
- When generating Info.plist from templates, fail the generator if the identifier substitution is empty.
- Unit-test plist generation against the final artifact in CI.
When it happens
Trigger: Contents/Info.plist contains `<key>CFBundleIdentifier</key><string></string>`. plutil extracts the empty string successfully, and this explicit emptiness check fires.
Common situations: Templated Info.plist where the identifier placeholder was never substituted; manual plist editing that wiped the value; a generator writing the key with an unset variable.
Related errors
- bundle identifier {id:?} is longer than 155 characters
- bundle identifier {id:?} has an empty segment
- plutil could not read CFBundleIdentifier from {}: {}
- helper plist {} has no CFBundleIdentifier
- icon sets are not supported in --hmr mode yet
AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20).
Data as JSON: /api/errors/8626800e090ddc55.
Report an issue: GitHub.