Process substitution causes indefinite hang - orphaned grandchild processes not terminated

Resolved 💬 3 comments Opened Dec 10, 2025 by ghul0 Closed Dec 11, 2025
💡 Likely answer: A maintainer (etraut-openai, contributor) responded on this thread — see the highlighted reply below.

What version of Codex is running?

codex-cli 0.66.0

What subscription do you have?

PRO

Which model were you using?

gpt-5.1-codex-max

What platform is your computer?

Linux 6.8.0-87-generic x86_64 x86_64

What issue are you seeing?

When Codex executes shell commands containing bash process substitution
(e.g., exec > >(tee -a file.log) 2>&1 && command), grandchild processes
like tee remain orphaned after the main command completes successfully.

Symptoms:

  • Codex hangs indefinitely waiting for command completion
  • raw_output.jsonl shows: "exit_code": null, "status": "in_progress"
  • Orphaned processes visible in ps: tee, timeout, python in sleeping state (S)
  • The actual command completes successfully (tests pass), but Codex never receives EOF

Example from logs:
``json
{
"type": "item.started",
"item": {
"type": "command_execution",
"command": "exec > >(tee -a /tmp/test.log) 2>&1 && python -m pytest tests/ -q",
"exit_code": null,
"status": "in_progress"
}
}
``
Process state after hang:
| PID | PPID | S | ELAPSED | CMD |
|--------|--------|---|---------|------------------------------|
| 135079 | 134817 | S | 01:06 | timeout 10m python -m pytest ... |
| 135084 | 135079 | S | 01:06 | tee -a /tmp/pytest.log |
| 135085 | 135079 | S | 01:06 | python -m pytest ... |

What steps can reproduce the bug?

Minimal reproduction

  1. Run Codex with a command using process substitution:

``bash
codex exec --dangerously-bypass-approvals-and-sandbox \
"exec > >(tee -a /tmp/test.log) 2>&1 && echo 'test passed'"
``

  1. Wait ~5-10 seconds, then check for orphaned processes:

``bash
pgrep -af 'tee.*test.log'
``

  1. Observe that tee process remains running even though echo completed.

## Full reproduction script

```bash
#!/bin/bash
# Save as /tmp/codex_hang_repro.sh
set -euo pipefail

# Record PIDs before test
BEFORE=$(pgrep -f 'tee.*codex_test' 2>/dev/null || true)

# Run codex with process substitution
timeout 30s codex exec --dangerously-bypass-approvals-and-sandbox \
"exec > >(tee -a /tmp/codex_test.log) 2>&1 && echo test" &
CPID=$!

sleep 10

# Check for orphaned processes
AFTER=$(pgrep -f 'tee.*codex_test' 2>/dev/null || true)
if [[ -n "$AFTER" ]]; then
echo "BUG REPRODUCED: Orphaned tee process found"
ps -p $AFTER -o pid,ppid,state,etime,cmd
kill -9 $AFTER 2>/dev/null
exit 1
fi
echo "No hang detected"
```

## Environment

  • Shell: bash
  • Note: Direct command execution works fine (~0.1s)
  • Note: Issue only occurs when Codex spawns the shell

What is the expected behavior?

When the main command completes (e.g., echo or pytest), all child processes
including those created by process substitution (tee) should be terminated,
and Codex should receive the exit code and return control to the user.

Expected:

  • Command completes in <1 second
  • All child processes terminated
  • exit_code: 0 reported
  • No orphaned processes

Additional information

_No response_

View original on GitHub ↗

3 Comments

etraut-openai contributor · 8 months ago

Thanks for the analysis and repro steps! Your bug reports are very high quality compared to most we receive. :)

sayan-oai contributor · 8 months ago

Hey @ghul0, I wasn't able to reproduce using Ubuntu 22, bash, and Codex v0.66. I tried both the minimal and full setup steps you gave.

Would you mind sharing the thread-id of a session where you see this issue? You can get the thread-id via the /feedback command in the CLI. Thanks.

ghul0 · 8 months ago

I cannot reproduce it as well on codex 0.69. It may be already fixed, I reached my limit on codex so will not work on that anymore.