Code Mode functions.wait can report completion/termination while child processes keep running
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.5k
- PR merge metrics
- PR metrics pending
Description
What version of Codex CLI is running?
codex-cli 0.147.0
What platform is your computer?
linux amd64
What issue are you seeing?
In Code Mode, functions.exec / functions.wait can report a cell as terminal while the command's child process is still alive.
We have observed this class three times. Two concrete shapes:
- A long-running local child, e.g. a cell that ultimately runs:
python3 -c 'import time; time.sleep(300)'
functions.exec yields quickly, then functions.wait reports a terminal/completed result before the child exits. A process-table check immediately after the reported completion shows the child PID still alive and consuming resources.
- A nested command that starts an SSH child.
functions.execstarts a cell that runs an SSH command; an immediatefunctions.wait({ terminate: true })reportsScript terminated, but the remote command continues and completes its side effects about 25 seconds later.
Expected behavior
For local children, functions.wait should not report a terminal completed / terminated outcome until the process group it owns has actually exited, or it should return an explicit warning that descendants are still alive.
For SSH/remote descendants, terminate: true should either close the local SSH process strongly enough that the remote command receives HUP/TERM, or the result should explicitly say that remote descendants are outside the termination guarantee.
Actual behavior
The Code Mode wrapper reports a terminal status while work is still running. An orchestrator that trusts the terminal status can launch duplicate expensive validators or proceed under the false assumption that a mutating command was stopped.
Why this appears to be upstream Code Mode behavior
On our side, containment around ended Codex sessions is green: we snapshot/kill the local process tree on disconnect/abort and verified no init-reparented CPU-burning local cell shells after managed session teardown. The misleading part is the Code Mode wait/terminate status itself.
The Code Mode host appears to be the component emitting the premature terminal result; Oivo only observes the begin/end tool messages around it.
Related issues
This is related to, but narrower than, #34115 (unified exec drops canonical process identity / hides a live background wait). This report is specifically about Code Mode functions.wait / terminate returning a terminal status that contradicts process liveness.
#35108 also mentions nested functions.exec / wait-agent behavior, but the failure mode here is not repeated parent polling; it is a terminal status while child work is still alive.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the Code Mode entry points for functions.exec and functions.wait, then trace how local process groups and SSH children are tracked and terminated. Reproduce the reported long-running Python child and nested SSH cases; done means terminal results reflect process-group liveness or explicitly warn about remaining descendants and remote termination limits.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100