Hmbown/CodeWhale · critical · Error
The release is missing its bundled runtime.
Error message
The release is missing its bundled runtime.
What it means
After signature and notarization checks, verifyReleaseBundle confirms the bundle ships its bundled Node runtime at Contents/MacOS/node. A notarized but incomplete bundle — validly signed yet missing the runtime the daemon needs — is rejected so a half-published release can never replace a working install.
Solutions
- Rebuild the release bundle ensuring node is copied into Contents/MacOS before signing and notarization
- Re-download the official release and re-verify (the current copy may be truncated)
- Check validateReleaseZip/extraction logic if a local extraction dropped the file
- Inspect the staged bundle with ls Contents/MacOS to confirm what is actually present
Example fix
// before (bundle staged without runtime)
code.verifyReleaseBundle(staged); // throws: missing bundled runtime
// after
code.fs.mkdirSync(path.join(staged, "Contents", "MacOS"), { recursive: true });
code.fs.copyFileSync(path.join(runtimeDir, "node"), path.join(staged, "Contents", "MacOS", "node"));
code.verifyReleaseBundle(staged); Defensive patterns
Strategy: validation
Validate before calling
if (!fs.existsSync(path.join(bundle, "Contents", "MacOS", "node"))) {
throw new Error("bundle missing bundled node runtime");
} Try / catch
try {
verifyReleaseBundle(bundle);
} catch (e) {
if (e.message.includes("missing its bundled runtime")) {
discardStagedBundle(bundle); // fail closed, keep current install
} else throw e;
} Prevention
- Add a packaging CI step asserting Contents/MacOS/node exists before signing
- Rebuild the bundle if any packaging step changes runtime paths
- SHA-verify the downloaded archive before staging
- Never hand-assemble release bundles; use the standard packer
When it happens
Trigger: Verifying a release bundle whose Contents/MacOS/node is absent: a packaging step skipped the runtime, an extraction dropped it, or a manually assembled bundle was signed without including node.
Common situations: Release packaging regression where the runtime copy step was removed or its path changed; a ZIP validation/extraction bug silently omitting an entry; someone rebuilt the bundle by hand and forgot the node binary.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- application not found — call list_apps for exact names/pids
- background preview capture failed
- choose one available display for recording
- durationSec must be positive
- element does not belong to the bound application —…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/bf56f2259f3ae28c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/plugins/computer-use/app/install-macos.mjs:45
return { backup };
} finally { fs.rmSync(staging, { recursive: true, force: true }); }
}
export function verifySignature(bundle) {
const result=spawnSync("codesign",["--verify","--deep","--strict",bundle],{encoding:"utf8"});
if(result.status!==0) throw new Error(`The app signature did not verify: ${result.stderr?.trim() ?? "codesign unavailable"}`);
}
export function verifyReleaseBundle(bundle) {
verifySignature(bundle);
const requirement='=anchor apple generic and identifier "net.codewhale.computer-use" and certificate leaf[subject.OU] = "5RDNSHA5TY"';
for(const [command,args] of [["/usr/bin/codesign",["--verify","--strict","-R",requirement,bundle]],["/usr/sbin/spctl",["--assess","--type","execute","--verbose=2",bundle]]]) {
const result=spawnSync(command,args,{encoding:"utf8"});
// Gatekeeper ships with macOS. Requiring its notarized source also rejects
// local allow-list overrides; consumer Macs do not need Xcode's stapler.
if(result.status!==0 || (command.endsWith("/spctl") && !/^source=Notarized Developer ID\r?$/m.test(result.stderr))) throw new Error("The update is not a valid notarized Codewhale release. Your current app has been kept.");
}
if(!fs.existsSync(path.join(bundle,"Contents","MacOS","node"))) throw new Error("The release is missing its bundled runtime.");
}
View on GitHub (pinned to 73e0f67d83)