Node REPL sandbox blocks Chromium/Playwright launch — MachPortRendezvousServer bootstrap_check_in denied (1100)
Summary
Chromium (via the bundled Playwright) cannot launch from the Codex Node REPL. The browser process aborts at Mach service check-in with Permission denied (1100) (BOOTSTRAP_NOT_PRIVILEGED). The same bundled Playwright binary launches successfully from a normal elevated shell, so this is specific to the sandbox/seatbelt profile applied to the REPL child process, not to Playwright or the browser cache.
Environment
- Codex.app: 26.623.141536 (build 4753)
- Bundled Node: v24.14.0
- Bundled Playwright: 1.57.0 (
/Applications/Codex.app/Contents/Resources/cua_node/lib/node_modules/playwright) - Chromium headless-shell revision: 1200 (and 1228)
- macOS: 26.5.2 (25F84), Apple Silicon (arm64)
Steps to reproduce
In the Codex Node REPL:
const pw = await import('playwright');
const browser = await pw.chromium.launch({ headless: true });
await browser.close();
Actual result
browserType.launch: Target page, context or browser has been closed
FATAL:base/apple/mach_port_rendezvous_mac.cc:156
Check failed: kr == KERN_SUCCESS.
bootstrap_check_in org.chromium.Chromium.MachPortRendezvousServer.<pid>: Permission denied (1100)
Also logged before the SIGTRAP:
ThermalStateObserverMac unable to register to power notifications
DNS config watch failed to start / Failed to read DnsConfig
Directly launching the chromium_headless_shell binary from the REPL fails identically.
Expected result
browser.close() returns cleanly, as it does from a normal shell.
Confirmation it is the sandbox, not Playwright/cache
The identical binary works outside the REPL. Smoke script run from an elevated shell:
// /private/tmp/gchrenov_playwright_smoke.mjs
import { chromium } from '/Applications/Codex.app/Contents/Resources/cua_node/lib/node_modules/playwright/index.mjs';
const browser = await chromium.launch({ headless: true });
await browser.close();
console.log('playwright launch ok');
$ node /private/tmp/gchrenov_playwright_smoke.mjs
playwright launch ok
Runnable scripts (smoke test + the verify and compare-probe QA scripts): https://gist.github.com/kjdaby87/5293147f3b070f1b0e3fc1f2f48d848f
Root cause (analysis)
Error 1100 = BOOTSTRAP_NOT_PRIVILEGED. Chromium's multi-process model requires the browser process to register a Mach service (bootstrap_check_in for MachPortRendezvousServer) so child processes (renderer/GPU/zygote) can rendezvous. The REPL's macOS seatbelt sandbox does not permit mach-register for the org.chromium.Chromium.MachPortRendezvousServer.* global name, so check-in fails and the process traps. This fires on every launch, including --headless; no Chromium launch flag bypasses it (--no-sandbox / --single-process do not help — the rendezvous server is constructed regardless).
Suggested fix
Add a mach-register allowance for the Chromium rendezvous global-name prefix to the Node REPL's sandbox profile, e.g.:
(allow mach-register (global-name-prefix "org.chromium.Chromium.MachPortRendezvousServer"))
(Chromium/Electron ship an analogous allowance in their own seatbelt profiles.) If browser automation from the REPL isn't intended to be supported, documenting that — and pointing users to run Playwright from a shell — would also resolve the confusion.
Impact / workaround
Browser automation (Playwright QA) from the Node REPL is unusable. Workaround: run Playwright from an elevated shell outside the REPL, which works reliably.