openai / openai/codex

app-server: silent exit 0 mid-turn immediately after a shell tool call, in read-only sandbox (macOS)

Open
#40,010 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app-server bug CLI sandbox
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

Summary

codex app-server reliably exits mid-turn with exit code 0, no signal, no stderr as soon as the model issues 1-2 shell tool calls during a read-only sandbox turn. No turn/completed notification, no error notification, no crash — the child process just terminates cleanly and the JSON-RPC client is left with a turn that will never resolve.

Reproduced 8/8 times across:

  • A CLI upgrade (0.142.5 → 0.149.0)
  • A clean uninstall + reinstall of @openai/codex (ruling out a corrupted install)

Environment

  • codex-cli 0.149.0 (@openai/codex npm package, installed globally)
  • macOS (Darwin), Apple Silicon
  • codex app-server invoked as a long-lived detached child process, driven over stdin/stdout JSON-RPC (initializethread/startturn/start), via a third-party wrapper (a Claude Code plugin) — same architecture described in #21813 and #21937.

Repro sequence

  1. initialize, then thread/start with sandbox: "read-only", approvalPolicy: "never".
  2. turn/start with a prompt that requires reading a large file and reasoning over it.
  3. Server emits turn/started correctly.
  4. Model issues 1-2 shell tool calls (e.g. rg -n ..., sed -n '149,230p' <file>). Both are reported as completed successfully (item/completed, exit 0) via notifications.
  5. Immediately after the second tool call's item/completed, the codex app-server process itself exitsexit code 0, signal: null, stderr empty. No turn/completed, no error notification ever arrives.
  6. A trivial prompt with zero tool calls ("reply with exactly X") completes successfully every time on the same setup. Only turns where the model makes a shell tool call while in read-only sandbox mode reproduce this.

What I checked

  • Not a Node version issue on the client side — same client code, same failure, across two codex CLI versions.
  • Not a corrupted/stale global install — clean npm uninstall -g @openai/codex + npm install -g @openai/codex@latest reproduces identically.
  • Not a client-side hang — I instrumented the JSON-RPC client with a watchdog + proper exit-event wiring; it now correctly observes the app-server process exiting (code 0, no signal) rather than hanging forever waiting on a promise that was never rejected.
  • Tried isolating to detached vs. foreground invocation shape; the two closest existing reports (#21813, #21937) both involve app-server spawned as a detached background child by a wrapper, same as this setup, which may be a relevant common factor.

Possibly related

  • #21937 — closest symptom match: worker silent death after a parallel-command burst, Turn completed never fires (Linux/WSL2).
  • #21813 — detached task-worker exits without writing failed status on broker socket disconnect — same detached-wrapper architecture.
  • #26533 — app-server stdout hits EOF mid-turn while the process stays alive (Windows) — different trigger (prompt content vs. tool calls), same "no terminal event, ever" shape.
  • #18243 — macOS-specific: shell execution silently fails in workspace-write/read-only sandbox via the sibling mcp-server transport; danger-full-access avoids it. As a workaround, switching this setup's sandbox from read-only to danger-full-access also avoids the silent exit here, which points at the sandbox subsystem (Seatbelt on macOS) as a plausible common cause across all of these reports, though I have no direct evidence of why it kills the parent process rather than just the sandboxed child.

Expected behavior

Either the turn completes normally, or the app-server surfaces a real error notification / non-zero exit / signal when something goes wrong — not a silent, clean exit 0 mid-turn with no diagnostic of any kind.

Workaround in use

Forcing sandbox: "danger-full-access" instead of read-only avoids the silent exit in this setup. Not a real fix — it gives up the read-only guarantee entirely just to get turns to complete.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the initialize, thread/start, and turn/start JSON-RPC sequence with sandbox set to read-only, then inspect the codex app-server path handling shell tool completion and process exits on macOS. Compare the behavior with danger-full-access and verify that a failing turn emits turn/completed or error rather than ending with a clean exit 0.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, rust, shell
Domain
backend-api-design, operating-systems, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.