{"record":{"id":"c8fed6725d24ebd0","repo":"denoland/deno","slug":"codesigning-requires-a-macos-build-host-uses-cod","errorCode":null,"errorMessage":"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.","messagePattern":"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\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/tools/desktop.rs","lineNumber":2593,"sourceCode":"}\n\n/// Codesign the macOS bundle in place. Signs every helper `.app` and\n/// the embedded CEF framework first, then the main bundle (signatures\n/// nest: the outer signature's CodeDirectory hashes the inner ones, so\n/// outer-last is the only order that works).\n///\n/// Re-uses the JIT entitlements that ship with the laufey CEF bundle\n/// (`Contents/Frameworks/<helper>.app/Contents/Resources/...entitlements...`\n/// or, more robustly, the per-helper entitlements laufey bundles next to\n/// each helper). When entitlements aren't present we fall back to\n/// signing without them — the binary will still launch but V8 won't\n/// get JIT permission.\nfn codesign_macos_bundle(\n  app_bundle: &Path,\n  identity: &str,\n) -> Result<(), AnyError> {\n  if !cfg!(target_os = \"macos\") {\n    bail!(\n      \"codesigning requires a macOS build host (uses `codesign(1)`). \\\n       Run `deno desktop` on macOS, or drop `macos.codesignIdentity` \\\n       from your deno.json when cross-building.\"\n    );\n  }\n  if identity.is_empty() {\n    bail!(\"macos.codesignIdentity is empty\");\n  }\n  log::info!(\n    \"{} bundle with identity {:?}\",\n    colors::green(\"Codesigning\"),\n    identity,\n  );\n\n  // Read the bundle id from the main Info.plist so we can override the\n  // signed identifier on `Contents/MacOS/laufey`. The default identifier\n  // codesign infers from a bare Mach-O binary is `laufey` (the basename),\n  // which doesn't match the .app's CFBundleIdentifier — and UN refuses","sourceCodeStart":2575,"sourceCodeEnd":2611,"githubUrl":"https://github.com/denoland/deno/blob/f7822238cab635a3a19f99f493f675fa81a7f9d8/cli/tools/desktop.rs#L2575-L2611","documentation":"codesign_macos_bundle shells out to macOS-only codesign(1). When the deno CLI itself is running on Linux or Windows but macos.codesignIdentity is set in the desktop config, it refuses to proceed instead of silently shipping an unsigned (or wrongly signed) bundle. The bail happens before any signing work is attempted.","triggerScenarios":"Cross-building a macOS .app/.dmg: running `deno desktop` on a Linux or Windows host while deno.json contains a non-empty macos.codesignIdentity entry. The cfg!(target_os = \"macos\") check on the *build host* fails, not the target.","commonSituations":"Linux CI pipelines that try to produce signed macOS artifacts in one job; developers on Windows configuring the whole desktop section upfront including signing, then building locally.","solutions":["Remove macos.codesignIdentity from deno.json (or set it only in a macOS-specific config) when building on non-macOS hosts.","Move the signing step to a macOS runner/job: build unsigned elsewhere, then run `deno desktop` on macOS with the identity set.","Gate the key on the host OS in CI, e.g. inject macos.codesignIdentity only when uname is Darwin."],"exampleFix":"// deno.json — before (breaks on Linux CI)\n\"desktop\": { \"macos\": { \"codesignIdentity\": \"Developer ID Application: ACME Inc\" } }\n\n// after: only set it on macOS hosts\n\"desktop\": { \"macos\": { \"codesignIdentity\": \"${MACOS_CODESIGN_IDENTITY:-}\" } }\n// with CI exporting MACOS_CODESIGN_IDENTITY only on the macOS job","handlingStrategy":"validation","validationCode":"# Only set the signing key on macOS hosts\nif [ \"$(uname -s)\" != \"Darwin\" ]; then\n  jq 'del(.desktop.macos.codesignIdentity)' deno.json > deno.tmp && mv deno.tmp deno.json\nfi\ndeno desktop ...","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep one deno.json per platform or template the signing key from an env var set only on macOS CI jobs.","Treat macos.codesignIdentity as a macOS-runner-only setting in pipeline docs.","Assert the host OS in the build script before invoking signing-capable commands."],"tags":["desktop","macos","codesign","cross-compilation","ci"],"backgroundTag":"cross-compilation-host-unsupported","analyzedSha":"f7822238cab635a3a19f99f493f675fa81a7f9d8","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}