Sandbox-First Execution
Core Rule
Always run Bash commands sandboxed first. Never set dangerouslyDisableSandbox: true unless a sandboxed attempt has already failed in this session, or the command is listed in skip_failure_requirement (see Configured Exceptions below).
When a Sandboxed Command Fails
Before retrying with dangerouslyDisableSandbox:
- Read the error. What specifically failed?
- Is it a sandbox restriction? Look for:
- "Operation not permitted" (filesystem write outside allowed paths)
- "Connection refused" or network timeouts (host not in allowedHosts)
- "Permission denied" on paths outside the project
- macOS Mach port / XPC denial — crash containing
bootstrap_check_in
and "Permission denied (1100)". The surface error looks like an application crash (e.g. Chromium Check failed: kr == KERN_SUCCESS), but the root cause is seatbelt denying mach-register/mach-lookup for a service. Seen with Playwright launching headless Chromium, and applies to other multi-process macOS tools (Electron, Puppeteer, etc.). Sandbox config cannot grant Mach port access, so this genuinely requires dangerouslyDisableSandbox.
- Suggest a config fix. Tell the user what to add to
~/.claude/settings.json: - Network: add host to
sandbox.network.allowedHosts - Filesystem: add path to
sandbox.filesystem.allowWrite - If retrying unsandboxed, explain what restriction was hit and why the sandbox
config change would be the better long-term fix.
Configured Exceptions
Some commands are known to always fail in the sandbox (e.g. docker, colima ssh). These can be configured in ~/.claude/sandbox-first.json or .claude/sandbox-first.json under the skip_failure_requirement key. The enforcement hook will allow dangerouslyDisableSandbox: true for these commands without requiring a prior sandboxed failure.
What NOT to Do
- Do not preemptively use
dangerouslyDisableSandboxbecause you think a command
"might" fail in the sandbox. Try it first.
- Do not silently retry unsandboxed after a sandbox failure. Always surface what happened.
- Do not use
dangerouslyDisableSandboxfor convenience. It exists for cases where the
sandbox genuinely cannot support the operation.