macOS 15.7.7: Code Mode crashes with SIGTRAP in V8 SetPermissions when entitlements are ignored

Open 💬 9 comments Opened Jun 10, 2026 by omggga
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Summary

After installing the latest macOS update around 2026-06-06, the Codex CLI started crashing with Trace/BPT trap: 5 / SIGTRAP when Code Mode starts its runtime. This appears to be related to hardened runtime + V8 JIT executable-memory permissions: codesign reports that the binary contains an invalid entitlements blob, so macOS ignores those entitlements. Ad-hoc re-signing the binary locally with JIT entitlements stops the crash.

Environment

  • macOS: 15.7.7, build 24G720
  • Kernel: Darwin 24.6.0, x86_64
  • Machine: Intel MacBookPro15,1 class hardware
  • Standalone Codex CLI: codex-cli 0.139.0
  • Codex.app bundled CLI observed: codex-cli 0.138.0-alpha.7
  • Standalone binary path: ~/.codex/packages/standalone/current/bin/codex

Reproduction

From a terminal, run Codex normally and ask it to inspect a file so it starts Code Mode/tool execution, for example:

codex --no-alt-screen "look at AGENTS.md"

The TUI starts, but once the runtime begins executing tool code, the process exits with:

trace trap  codex

Crash report details

The macOS crash report shows:

Exception Type: EXC_BREAKPOINT (SIGTRAP)
Termination Reason: Trace/BPT trap: 5

The faulting thread stack includes:

v8::base::OS::SetPermissions(void*, unsigned long, v8::base::OS::MemoryPermission)
v8::internal::CodeRange::InitReservation(...)
v8::internal::Heap::SetUp
v8::internal::Isolate::Init
v8::internal::Isolate::InitWithSnapshot
v8::internal::Snapshot::Initialize
v8::Isolate::Initialize
v8::Isolate::New
codex_code_mode::runtime::spawn_runtime

In the crashing report, the register state had rdi = 13, consistent with EACCES from the memory permission change.

Codesign observations

Before applying the workaround, both the standalone CLI binary and the Codex.app bundled resource CLI reported:

warning: binary contains an invalid entitlements blob. The OS will ignore these entitlements.

The standalone binary was signed with hardened runtime before the local workaround:

Identifier=codex
TeamIdentifier=2DC432GLL2
flags=0x10000(runtime)

Confirmed workaround

Creating an entitlements plist containing:

<dict>
  <key>com.apple.security.cs.allow-jit</key>
  <true/>
  <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
  <true/>
</dict>

and then re-signing the installed standalone binary locally fixes the crash:

codesign --force --sign - --entitlements /private/tmp/codex-jit.entitlements \
  ~/.codex/packages/standalone/current/bin/codex

After that, the same codex --no-alt-screen "look at AGENTS.md" scenario runs successfully, executes tool commands, and produces a normal answer. No new codex-*.ips crash report is generated.

Expected behavior

The distributed Codex CLI binaries should have valid entitlements for the embedded V8/Code Mode runtime on macOS, so users do not need to ad-hoc re-sign the binary after every update.

Actual behavior

After the macOS update, the official binary's entitlements appear to be ignored by the OS, V8 fails while setting executable memory permissions, and Codex exits with SIGTRAP during Code Mode runtime startup.

View original on GitHub ↗

9 Comments

github-actions[bot] contributor · 1 month ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #27305
  • #26988

Powered by Codex Action

Oxygen56 · 1 month ago

Root Cause Analysis

I've investigated this crash and identified the cause. Here's the breakdown:

V8 JIT Memory Model

V8's Code Mode runtime uses a two-stage JIT compilation pipeline:

  1. mmap(addr, len, PROT_READ|PROT_WRITE, MAP_JIT) — allocate writable JIT memory
  2. mprotect(addr, len, PROT_READ|PROT_EXEC) — flip to executable

The second mprotect() call requires com.apple.security.cs.allow-unsigned-executable-memory under Hardened Runtime. Without it, the kernel returns EACCES (errno 13, visible in rdi register from the crash report), and V8 traps.

Why the Current Binary Fails

The current entitlements plist (.github/scripts/macos-signing/codex.entitlements.plist) only declares:

  • com.apple.security.cs.allow-jit

But is missing:

  • com.apple.security.cs.allow-unsigned-executable-memory

allow-jit alone enables MAP_JIT allocation but does not cover the subsequent mprotect() permission transition that V8 requires. macOS 15.7+ appears to enforce this more strictly than prior versions.

Why Your Workaround Works

Your manual codesign --force --sign - with both entitlements produces a valid, correctly-formatted signature blob containing the full set of permissions V8 needs. This also resolves the "invalid entitlements blob" warning, which suggests the current release binary's entitlements were not correctly embedded during the rcodesign pipeline (separate issue from #26252 migration).

Precedent

All major JIT-capable runtimes ship both entitlements together:

  • Bun: allow-jit + allow-unsigned-executable-memory + disable-executable-page-protection
  • Electron/VS Code: allow-jit + allow-unsigned-executable-memory
  • .NET MAUI (PR #15745): Auto-adds allow-jit for ARM64 release builds

Proposed Fix

Add com.apple.security.cs.allow-unsigned-executable-memory to the entitlements plist. Single-line addition, zero regression risk.

This should also resolve #27305 and #26988 if they share the same root cause.

I'll submit a PR shortly.

Oxygen56 · 1 month ago

The fix is ready at Oxygen56:fix/v8-entitlements-macos-sigtrap-27358 — a single-line addition of allow-unsigned-executable-memory to the entitlements plist.

I wasn't able to open a PR directly (external PR creation appears to be restricted for this repo). Happy to have a maintainer open it on my behalf, or if the restriction is lifted I can submit directly.

The diff is minimal:

--- a/.github/scripts/macos-signing/codex.entitlements.plist
+++ b/.github/scripts/macos-signing/codex.entitlements.plist
@@ -4,5 +4,7 @@
 <dict>
 	<key>com.apple.security.cs.allow-jit</key>
 	<true/>
+	<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
+	<true/>
 </dict>
 </plist>
bolkhovsky · 1 month ago

Independent confirmation from a different distribution channel — Homebrew cask (/usr/local/Caskroom/codex/<version>/codex-x86_64-apple-darwin), reproduced on both 0.138.0 and 0.139.0.

Environment

  • Intel MacBook Pro (i5-8257U), macOS 15.7.4 (24G517), Darwin 24.6.0, x86_64
  • codex-cli 0.138.0 and 0.139.0 (brew cask)
  • Model: gpt-5.5 (which is tool_mode: "code_mode_only" in the model catalog, so every tool call goes through the V8 runtime)

Repro — 100% reproducible, crashes the moment the model executes its first command:

codex exec --skip-git-repo-check "Run the shell command 'echo hello' and tell me its output."

Pure-text turns (no tool calls) work fine. On 0.138.0 the V8 fatal error was printed to the terminal:

# Fatal error in , line 0
# Check failed: 12 == (*__error()).

i.e. an errno check failing inside V8 memory permission handling (we saw errno 12/ENOMEM in the check; the .ips reports are the same EXC_BREAKPOINT (SIGTRAP) / Trace/BPT trap: 5 in an unnamed V8 runtime thread). On 0.139.0 the process dies silently with exit 133.

Codesign on the brew cask binary supports @Oxygen56's analysis — no "invalid entitlements blob" warning here, the entitlements are embedded correctly but only contain allow-jit:

$ codesign -d --entitlements - codex-x86_64-apple-darwin
[Key] com.apple.security.cs.allow-jit
[Value] [Bool] true

flags=0x10000(runtime)  TeamIdentifier=2DC432GLL2

So this isn't only the broken-blob case from the standalone package: a validly signed hardened-runtime binary with allow-jit alone still traps, confirming com.apple.security.cs.allow-unsigned-executable-memory is genuinely required.

Signing-free workaround (for users who don't want to re-sign the binary after every update): take Code Mode out of the equation.

  • Quick: use a model without code_mode_only, e.g. codex -m gpt-5.4 — works flawlessly.
  • Keep gpt-5.5: copy ~/.codex/models_cache.json's models array into a file with "tool_mode": null for gpt-5.5, then in ~/.codex/config.toml:

``toml
model_catalog_json = "/Users/<you>/.codex/model_catalog_override.json"
``

Commands then run through the classic shell tool instead of the embedded V8 runtime; no crashes since. (Caveat: this pins the catalog snapshot until the line is removed.)

DerSchiman · 1 month ago

Same crash here on an Intel Mac mini (i7-8700B, macOS 15.7.7 / 24G720) — identical faulting stack ending in v8::base::OS::SetPermissions, triggered as soon as a session deploys a subagent or runs commands through unified_exec. I filed #27422 before noticing this one and closed it as a duplicate, but two findings from my machine that might help narrow the root cause:

The crash does not require an invalid entitlements blob. On my install the signature is fully intact — codesign --verify --strict passes and the entitlements decode cleanly:

Authority=Developer ID Application: OpenAI OpCo, LLC (2DC432GLL2)
flags=0x10000(runtime)
[Key] com.apple.security.cs.allow-jit  [Value] [Bool] true

So macOS was honoring the entitlements here, and it still crashes. The problem is that allow-jit by itself isn't sufficient on Intel: V8's code range setup uses plain RWX mmap/mprotect without MAP_JIT on x86_64, and under the hardened runtime that path additionally needs com.apple.security.cs.allow-unsigned-executable-memory.

I checked that in isolation with a minimal C program (RWX mmap, MAP_JIT mmap, RW→RWX mprotect), signed the same way the shipped binary is:

| signing | plain RWX mmap | MAP_JIT mmap | mprotect RW→RWX |
|---|---|---|---|
| hardened runtime + allow-jit only | EPERM | ok | EPERM |
| hardened runtime + both entitlements | ok | ok | ok |

That lines up with the EACCES you saw in the register state.

Other data points: reproduced on 0.138.0 and 0.139.0, and across npm, Homebrew cask and standalone installs, so it's not tied to a specific release or packaging. Same workaround as yours works here (ad-hoc re-sign keeping the hardened runtime, adding both entitlements) and has to be repeated after every codex update.

Suggested fix is the same conclusion you reached: add com.apple.security.cs.allow-unsigned-executable-memory to the entitlements used for the x86_64-apple-darwin release binaries — Chromium and Deno ship exactly that on Intel macOS.

Full crash report excerpt and codex doctor output are in #27422.

fjbarrett · 1 month ago

Independent confirmation from a third distribution channel — npm (@openai/codex@openai/codex-darwin-x64 vendor binary) — plus a verification of the proposed entitlements fix and a workaround that doesn't modify the binary.

Environment

  • Intel MacBook Pro (i7-8569U), macOS 15.7.7 (24G720), Darwin 24.6.0, x86_64, no Rosetta
  • codex-cli 0.138.0 and 0.139.0 via npm (also reproduced on the Homebrew cask 0.139.0 before removing it)
  • Model: gpt-5.5 (tool_mode: "code_mode_only" in the model catalog, so the first tool call of any session spawns the V8 runtime and crashes)
  • Binary: <npm prefix>/lib/node_modules/@openai/codex/node_modules/@openai/codex-darwin-x64/vendor/x86_64-apple-darwin/bin/codex

Supporting @DerSchiman's finding — no invalid entitlements blob required. On the npm binary the signature is fully intact:

  • codesign --verify --strict passes (valid on disk, satisfies its Designated Requirement, Authority=Developer ID Application: OpenAI OpCo, LLC (2DC432GLL2))
  • The entitlements blob decodes cleanly and contains only com.apple.security.cs.allow-jit
  • com.apple.security.cs.allow-unsigned-executable-memory is absent

So the missing entitlement alone is sufficient to crash; no signing corruption involved.

Verified @Oxygen56's proposed fix on this machine. Re-signing the binary ad hoc with allow-unsigned-executable-memory added (keeping allow-jit) eliminates the crash. Deterministic repro used:

codex exec --skip-git-repo-check --enable code_mode "Use your exec tool to run: echo hello"
  • Stock binary: exit 133, EXC_BREAKPOINT (SIGTRAP), faulting thread in v8::base::OS::SetPermissionsv8::internal::CodeRange::InitReservationHeap::SetUpIsolate::Init ← … ← v8::Isolate::New (identical stack across npm 0.138.0/0.139.0 and the brew cask 0.139.0)
  • Re-signed with the added entitlement: exit 0, tool call completes normally

Workaround that doesn't touch the binary (survives npm updates, keeps the Developer ID signature): point model_catalog_json at a copy of ~/.codex/models_cache.json with tool_mode removed from the gpt-5.5 entry, so tool calls fall back to direct mode and V8 is never spawned:

# ~/.codex/config.toml
model_catalog_json = "/Users/<you>/.codex/model_catalog_override.json"

Caveat: this replaces the model catalog process-wide, freezing the model list until removed. Feature flags are not a workaround — model_info.tool_mode from the catalog takes precedence over features.code_mode, which is why a session whose features=[…] list contains no CodeMode entry still crashes on gpt-5.5.

zhangdk · 1 month ago

I can reproduce the same crash.

Codex CLI: 0.139.0
Install: Homebrew cask
Binary: /usr/local/Caskroom/codex/0.139.0/codex-x86_64-apple-darwin
Symlink: /usr/local/bin/codex -> above binary
macOS: 15.7.5 (24G624)
Hardware: Intel MacBookPro16,2, x86_64
Model: gpt-5.5
Symptom: Codex exits with Trace/BPT trap: 5 when tool/code-mode runtime starts.

Crash report:
Exception: EXC_BREAKPOINT / SIGTRAP
Termination: Trace/BPT trap: 5
Faulting stack includes:

  • v8::base::OS::SetPermissions
  • v8::internal::CodeRange::InitReservation
  • v8::Isolate::New
  • codex_code_mode::runtime::spawn_runtime

codesign:

  • Identifier=codex
  • TeamIdentifier=2DC432GLL2
  • flags=0x10000(runtime)
  • entitlements include com.apple.security.cs.allow-jit

-

hapiii · 1 month ago

Independent confirmation on a newer macOS release. The crash is still reproducible with the current stable Codex CLI.

Environment

  • Codex CLI: 0.139.0
  • Install method: npm (@openai/codex@0.139.0)
  • Native package: @openai/codex-darwin-x64
  • macOS: 26.5.1 (25F80)
  • Hardware: Intel MacBook Pro (MacBookPro16,2), x86_64
  • Terminal: iTerm2 3.5.4
  • Model: gpt-5.5

Observed behavior
Codex exits abruptly during tool execution/code review and zsh prints:

trace trap  codex

I reproduced it multiple times on June 12, 2026. Each failure generated matching codex-*.ips and node-*.ips reports. The native Codex process crashes first; the npm Node launcher then re-emits the child signal.

The native crash report is identical to the reports above:

Exception: EXC_BREAKPOINT (SIGTRAP)
Termination: Trace/BPT trap: 5

v8::base::OS::SetPermissions(...) + 231
v8::internal::CodeRange::InitReservation(...) + 587
v8::internal::Heap::SetUp(...) + 399
v8::internal::Isolate::Init(...) + 1967
v8::internal::Isolate::InitWithSnapshot(...) + 9
v8::internal::Snapshot::Initialize(...) + 539
v8::Isolate::Initialize(...) + 603
v8::Isolate::New(...) + 55

The installed npm native binary reports:

codesign --verify --strict:
invalid signature (code or signature have been modified)

codesign -d --entitlements -:
com.apple.security.cs.allow-jit = true

This confirms that the issue also affects Intel Macs on macOS 26.5.1 and the npm distribution of 0.139.0. Sensitive account and local project path data have been omitted. Full .ips reports are available if maintainers need them.

hattori7243 · 1 month ago

same problem,intel chip mac is so hard to use codex