denoland/deno · error
macos.codesignIdentity is empty
Error message
macos.codesignIdentity is empty
What it means
After the macOS-host check, codesign_macos_bundle rejects an empty signing identity string. The macos.codesignIdentity key is present in deno.json but its value is "" — an identity that cannot exist, and passing it to codesign(1) would only fail later with a more confusing error.
Source
Thrown at cli/tools/desktop.rs:2600
/// Re-uses the JIT entitlements that ship with the laufey CEF bundle
/// (`Contents/Frameworks/<helper>.app/Contents/Resources/...entitlements...`
/// or, more robustly, the per-helper entitlements laufey bundles next to
/// each helper). When entitlements aren't present we fall back to
/// signing without them — the binary will still launch but V8 won't
/// get JIT permission.
fn codesign_macos_bundle(
app_bundle: &Path,
identity: &str,
) -> Result<(), AnyError> {
if !cfg!(target_os = "macos") {
bail!(
"codesigning requires a macOS build host (uses `codesign(1)`). \
Run `deno desktop` on macOS, or drop `macos.codesignIdentity` \
from your deno.json when cross-building."
);
}
if identity.is_empty() {
bail!("macos.codesignIdentity is empty");
}
log::info!(
"{} bundle with identity {:?}",
colors::green("Codesigning"),
identity,
);
// Read the bundle id from the main Info.plist so we can override the
// signed identifier on `Contents/MacOS/laufey`. The default identifier
// codesign infers from a bare Mach-O binary is `laufey` (the basename),
// which doesn't match the .app's CFBundleIdentifier — and UN refuses
// notification authorization when the running binary's signed id
// doesn't match the bundle's id. Forcing `--identifier=<bundle_id>`
// makes them match.
let bundle_id = read_bundle_identifier(app_bundle)?;
// Sign helpers first (inside → outside). The order within helpers
// doesn't matter — they don't nest into each other.View on GitHub (pinned to f7822238ca)
Solutions
- Set a real identity, e.g. "Apple Development: dev@acme.com (ABCD1234)" or "Developer ID Application: ACME Inc (TEAMID)".
- If you don't intend to sign, delete the macos.codesignIdentity key entirely instead of leaving it empty.
- For unsigned local testing, ad-hoc signing with identity "-" is a non-empty value codesign accepts.
Example fix
// before
"macos": { "codesignIdentity": "" }
// after (real identity)
"macos": { "codesignIdentity": "Developer ID Application: ACME Inc (TEAMID)" }
// or remove the key entirely to skip signing Defensive patterns
Strategy: validation
Validate before calling
const identity = config.desktop?.macos?.codesignIdentity;
if (identity !== undefined && identity.trim() === "") {
throw new Error("macos.codesignIdentity must be a real identity or absent");
} Type guard
function isValidIdentity(v: unknown): v is string {
return typeof v === "string" && v.trim().length > 0;
} Prevention
- Fail fast in config loading on empty-string values for signing keys instead of shipping them.
- If templating config from env vars, substitute a sentinel and delete the key when unset.
- Run `security find-identity -v -p codesigning` once and paste the exact identity string.
When it happens
Trigger: deno.json contains "macos": { "codesignIdentity": "" } — typically from a template placeholder never filled in, or from env-var interpolation ("codesignIdentity": "$SIGN_ID") where the variable is unset and yields an empty string.
Common situations: Scaffolded desktop projects with placeholder config; CI where the secrets-to-config mapping produced an empty value; local testing where someone enabled the key 'to be filled later'.
Related errors
- codesigning requires a macOS build host (uses `codesign(1)`)
- plutil could not read CFBundleIdentifier from {}: {}
- codesign failed for {} (identity {:?})
- No valid icon images found for .icns
- SvelteKit detected, but no adapter that `deno desktop` can b
AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20).
Data as JSON: /api/errors/4731be03c1c73f1f.
Report an issue: GitHub.