Skip to content

fix(sandbox): don't crash the desktop when the VM helper is missing - #380

Merged
quickbeard merged 1 commit into
mainfrom
fix/vmm-helper-missing
Sep 25, 2026
Merged

quickbeard merged 1 commit into
mainfrom
fix/vmm-helper-missing

Conversation

@quickbeard

Copy link
Copy Markdown
Owner

Summary

bun dev:desktop on macOS with Swift 6.4 (Command Line Tools 27) showed:

A JavaScript error occurred in the main process — Uncaught Exception: Error: spawn …/packages/codev-sandbox/native/vzhelper/dist/codev-vmm ENOENT

Two causes, both fixed here:

1. A failed helper spawn crashed the main process. createVzProvider().start() spawned codev-vmm and listened for exit, stdout and stderr, but not error. When the binary is missing, Node emits error and never exit (ChildProcess._handle.onexit, the frame in the dialog), so it became an uncaught exception in Electron's main process.

  • This fires at launch because sandbox autostart calls start() directly. availability(), which does check for the helper, is only consulted by the UI.
  • start() now handles error:
    • ENOENT → "sandbox VM helper is not installed (expected at …)", the same message availability() gives;
    • any other spawn error → "could not run the sandbox VM helper: …".
  • The start then fails through the existing failure() path, so the sandbox shows an error instead of crashing the app.

2. The helper never got built. predev.ts builds codev-vmm for dev runs and deliberately treats failure as non-fatal. On Swift 6.4, swift build defaults to the new swiftbuild backend, which fails on Command Line Tools setups before compiling anything ("Could not initialize build system … Unknown error parsing property list"). So the build always failed, quietly.

  • build-vzhelper.ts now retries a failed swift build with --build-system native, which still builds this package (SwiftPM warns that it's deprecated). Toolchains whose default works never take the retry.
  • An up-to-date rebuild still takes about 1.5 s.

packages/codev-sandbox is fork-only, so no DIVERGENCES.md row.

Not covered: release packaging's --universal build has a second CLT 27 problem. The x86_64 slice fails to link because the toolchain's Swift compatibility libraries are arm64-only. That needs a decision about dropping the back-compat shims for Intel macOS 12.0–12.2 and is left out here; dev builds are host-arch only.

Test plan

  • New provider test using the real spawn on a missing helper: start() rejects with the "not installed" message. Without the fix it fails with "Unhandled error … ENOENT".
  • bun test in packages/codev-sandbox (191 pass)
  • bun typecheck in packages/codev-sandbox and packages/desktop
  • bun script/build-vzhelper.ts on Swift 6.4 / CLT 27: falls back to the native build system, produces dist/codev-vmm signed with com.apple.security.virtualization; an up-to-date rerun takes ~1.5 s
  • bun dev:desktop on the reporting machine: no crash dialog, and sandboxes start with the freshly built helper

🤖 Generated with Claude Code

`bun dev:desktop` on a Mac with Swift 6.4 (Command Line Tools 27) opened
"A JavaScript error occurred in the main process: spawn .../codev-vmm
ENOENT". Two causes:

- The vz provider spawned codev-vmm without an "error" listener. A spawn
  that fails emits "error" and never "exit", so the event was an uncaught
  exception in Electron's main process — triggered at launch by sandbox
  autostart, which does not go through availability()'s helper check.
  start() now fails with "sandbox VM helper is not installed (expected at
  …)" (or the spawn error) instead.
- The helper was never built: Swift 6.4 defaults `swift build` to the
  swiftbuild backend, which fails on Command Line Tools setups ("Could not
  initialize build system ... Unknown error parsing property list"), and
  predev deliberately treats a failed helper build as non-fatal.
  build-vzhelper.ts now retries a failed build with `--build-system
  native`, so toolchains whose default works are unaffected.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@quickbeard
quickbeard merged commit 60fab45 into main Sep 25, 2026
0 of 5 checks passed
@quickbeard
quickbeard deleted the fix/vmm-helper-missing branch September 25, 2026 10:30
quickbeard added a commit that referenced this pull request Sep 25, 2026
…381)

Release packaging (desktop prebuild → build-vzhelper.ts --universal)
failed on Command Line Tools 27 / Swift 6.4: the helper's macOS 12
deployment target links Swift's back-compatibility libraries
(libswiftCompatibility56, libswiftCompatibilityPacks), and this toolchain
ships every one of them for arm64/arm64e only, so the x86_64 slice failed
to link ("fat file missing arch 'x86_64'", undefined symbols). macOS
releases had to be built by hand.

When the toolchain's libswiftCompatibility56.a has no x86_64 slice, the
Intel slice is now built with `-runtime-compatibility-version none`. The
arm64 slice keeps the libraries, and a toolchain that still ships Intel
copies keeps them for Intel too; the only cost is Intel Macs on macOS
12.0–12.2 running the helper without those runtime fixes.

Also quiets the failed first attempt on the default build system before
the `--build-system native` retry (#380), so a successful build no longer
logs a wall of errors.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant