-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Description
What version of Codex is running?
codex-cli 0.42.0
Which model were you using?
gpt-5-codex
What platform is your computer?
Linux 6.6.87.2-microsoft-standard-WSL2 x86_64 unknown
What steps can reproduce the bug?
When a shell tool call times out, Codex only kills the shell wrapper (bash -lc), not its child processes. These orphaned children keep stdout/stderr pipes open, even causing Codex to hang indefinitely in some cases despite the 366s wrapper timeout.
Steps to Reproduce
On any Linux machine:
- Launch Codex (CLI or desktop).
- Run (with a 5-second timeout):
mkfifo pipe.$$; (while true; do echo child; sleep 1; done) > pipe.$$ & cat pipe.$$
- Wait for the five-second timeout. Codex logs that the tool call timed out, but the UI remains on "working".
- In another terminal, run
ps -ef | grep '[p]ipe'
(or inspect the loop). Both the background writer andcat
are still running.
Observed Behavior
Even after the timeout, the child pipeline keeps running. Because those descendants keep the stdout pipe open, Codex's reader tasks never finish, so the turn remains stuck until you manually interrupt.
Expected Behavior
When a tool call times out, Codex should terminate the entire process tree so stdout and stderr close, the readers exit, and the tool call finishes cleanly.
Additional Notes
A real-world example is cargo test --release
with a timeout. Cargo's child runners survive the timeout, continue emitting output, and Codex stays in "working" until you abort the turn.
Root Cause
- Commands wrapped in
bash -lc
create a shell wrapper process. - On timeout, only the wrapper is killed via its PID.
- Child processes become orphaned but keep running.
- They hold stdout/stderr pipes open indefinitely.
- Reader tasks block waiting for EOF that never arrives.
Fix
- Use
setsid()
to create process groups. - Kill the entire process group with
kill(-pid, signal)
. - Ensures all descendants terminate and pipes close properly.