codex exec silently crashes with no output when stdio is detached from TTY (0.124.0+)

Open 💬 2 comments Opened Apr 28, 2026 by KazukiAkimura

What version of Codex CLI is running?

codex-cli 0.125.0 (also reproduced on 0.124.0; 0.123.0 unaffected)

What subscription do you have?

ChatGPT Pro

Which model were you using?

gpt-5.5

What platform is your computer?

Linux 6.12.0-124.49.1.el10_1.x86_64 x86_64 unknown

What terminal emulator and version are you using (if applicable)?

N/A — failure occurs in a headless / non-TTY context spawned by Claude Code's Bash tool (run_in_background: true, equivalent to setsid). No interactive terminal emulator is involved on the failing path. For reference, the parent shell session is accessed via SSH from VSCode to the AlmaLinux server.

What issue are you seeing?

codex exec silently exits with empty stdout (0 bytes) when stdio is detached from a controlling TTY AND the prompt is long. The process produces no error, no panic message, no log entry — just an empty result. Short prompts under the same conditions sometimes succeed.

This regressed in 0.124.0 (binary mtime ~2026-04-24) and is still present in 0.125.0. 0.123.0 is unaffected.

Common factor for the failures: no controlling TTY + non-trivial prompt length.

Wrapping with script -qfc "codex exec ..." /dev/null (re-attaches a pseudo-TTY) restores function, but emits a codex_core::session: failed to record rollout items: thread <uuid> not found ERROR line.

Impact: blocks any orchestration that spawns codex exec from a parent agent (Claude Code, custom CI runners, MCP-based pipelines). The foreground-with-file-redirect workaround is incompatible with normal background / parallel job execution.

May share root cause with:

  • #10248 (codex exec --json panics with Broken pipe when stdout consumer closes)
  • tuannvm/codex-mcp-server#153 (codex exec hangs when spawned with stdio pipe)
  • paperclipai/paperclip#1749 (codex exec doesn't exit after piped stdin completes)

What steps can reproduce the bug?

Reproduction matrix:

| Invocation | TTY | Result |
|---|---|---|
| codex exec "<long prompt>" < /dev/null (foreground, TTY inherited) | present | ✅ produces output (~8.8KB) |
| setsid codex exec "<long prompt>" < /dev/null (foreground, no TTY) | detached | ❌ silent crash, 0B output |
| Spawned via Claude Code Bash tool with run_in_background: true (setsid-equivalent) | detached | ❌ silent crash, 0B output |
| setsid codex exec "<short prompt>" < /dev/null | detached | ✅ sometimes works |

Minimal repro on a Linux shell, inside a trusted Codex project directory:

yes "Please analyze this codebase and explain its architecture in detail." | head -c 2048 > prompt.txt

# FAIL: setsid + closed stdin (mimics Claude Code background tasks)
RUST_BACKTRACE=1 setsid codex exec "$(cat prompt.txt)" < /dev/null > out.log 2> err.log
echo "exit=$? out=$(wc -c < out.log) err=$(wc -c < err.log)"
# → exit=0 out=0 err=0   ← silent crash, no panic, no log line

# CONTROL: foreground, TTY inherited
codex exec "$(cat prompt.txt)" < /dev/null > out2.log 2> err2.log
echo "exit=$? out=$(wc -c < out2.log) err=$(wc -c < err2.log)"
# → exit=0 out=8804 err=491925   ← works

Workaround that works: keep the process in the foreground with stdout redirected directly to a file (no pipe, TTY inherited from the parent shell). Or wrap with script -qfc "codex exec ..." /dev/null to re-attach a pseudo-TTY.

Workaround that does not work: piping stdout to tee, tail, etc. while the process group is detached via setsid.

What is the expected behavior?

codex exec should run reliably without a controlling TTY, regardless of prompt length. Headless / CI / agent-orchestration use cases require this.

When the process cannot proceed for some reason, it should exit with a non-zero status and emit a diagnostic message to stderr — not exit 0 with empty output.

Additional information

Tested on a Podman-hosted AlmaLinux 10 VM (Node v24.13.1, codex installed via npm global). The same failure pattern is reproduced both via Claude Code's Bash tool (run_in_background: true) and via a direct setsid codex exec invocation in an SSH session, confirming that the trigger is the absence of a controlling TTY rather than anything Claude Code-specific.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗