TUI freeze after submitting `/side` (intermittent): recurring `sleep 180` sandbox respawns block main thread
Summary
In codex-cli 0.130.0 (Linux, npm-installed), submitting /side intermittently deadlocks the TUI. When the freeze happens, the CLI has spawned a sandboxed bash -c 'sleep 180' via bwrap, the main input thread blocks synchronously on that exec, and the sandbox respawns immediately when each 3-minute sleep ends — so the TUI never recovers without killing the codex process.
/side does not always freeze: same user, same machine, sometimes opens a working side-thread, sometimes deadlocks. When it freezes, subsequent /side attempts also freeze and stack additional sleep 180 processes under separate bwrap chains.
Reproduced twice in two separate codex resume invocations on the same machine within ~30 minutes.
Environment
codex-cli 0.130.0(npm-installed at~/.npm-global/bin/codex)- Linux 6.8.0-1052-aws, x86_64
bash5.x,tmux3.2a host shellbwrap(bubblewrap) sandbox enabled- No custom
~/.codex/config.tomloverrides for sandbox/network
Repro (intermittent)
- Launch
codex resumein a tmux pane. - Type
/sidein the compose buffer. - Press Enter to submit.
- Sometimes the side-thread opens normally and is usable. Other times the TUI freezes: the side-thread sandbox spawns a
bash -c 'sleep 180', the main input thread blocks synchronously on that exec, the footer status stops ticking, and no keystrokes (Esc / Ctrl-C / Backspace viatmux send-keys) get processed. - After 180s the sleep ends, a fresh sandbox respawns under a new bwrap chain within ~1s, and the cycle repeats indefinitely. Issuing additional
/sideinvocations during the freeze stacks more concurrentsleep 180processes.
Expected
- Submitting
/sideshould always open a responsive side-thread. - The sandboxed shell that backs the side-thread should run as a background task so the main TUI stays interactive (current Esc / Ctrl-C /
/quitshould work even while the sandbox is running). - A side-thread that fails to initialise should error visibly rather than silently spinning a 180-second-sleep loop.
Actual
- Each freezing
/sideinvocation spawns this process chain:
````
codex resume
└─ codex-linux-sandbox --sandbox-policy-cwd ... --command-cwd ...
└─ bwrap --new-session --die-with-parent ...
└─ bwrap (inner)
└─ bash -c 'sleep 180'
- Three concurrent
sleep 180processes were observed across panes, each parented to a separate sandbox chain, after stacking multiple/sideattempts during a freeze. - When one
sleep 180exits, a fresh one spawns within <1s under a new bwrap chain — render-loop-style respawn rather than a single one-shot warmup. ps -o etimesshowed thesleep 180PIDs continuously rolling over (e.g. 113s elapsed → killed → new one at 0s).- Pane stays at the same frozen TUI frame the entire time:
```
◦ Working (28m 01s • esc to interrupt)
› /side
/side start a side conversation in an ephemeral fork
```
Diagnostic evidence
ps chain at one capture:
PID PPID ETIME CMD
1394741 ... ... .../codex/codex resume
1411822 1394741 01:33 codex-linux-sandbox --sandbox-policy-cwd ...
1411826 1411822 ... bwrap --new-session --die-with-parent ...
1411827 1411826 ... bwrap (inner)
1411828 1411827 01:53 sleep 180
After killing the inner sleep 180, two new sleep 180s (PIDs 1413278, 1413297) appeared under fresh bwrap chains within seconds.
Workaround
kill -INT <codex-resume PID>exits the CLI cleanly and frees the pane. Any background work the agent had launched via SSH/tmux on remote machines continues uninterrupted (that's not the same as the local bwrap sandbox).- Once the TUI is frozen,
/sidekeystrokes typed viatmux send-keysdo not unfreeze it.
Likely root cause (speculative)
The sleep 180 looks like a "hold this sandboxed shell alive long enough for the side-thread to use it" mechanism. The intermittent nature suggests a race condition rather than a deterministic bug — possibly:
- The exec is run synchronously on the TUI's main input thread instead of a background task whenever the side-thread sandbox warmup happens to hit a slow path.
- There's a sandbox-setup retry/respawn loop that fires when the initial spawn doesn't complete a handshake in time, and once it gets into that loop the main thread never gets to drain the side-thread output that would tell it the sandbox is ready.
Either way the user-visible symptom is the same: TUI is unrecoverable until the process is killed.
Why this matters in practice
Both Codex CLI sessions where this reproduced had been driving long-running training/eval workflows for many hours. The freeze itself is recoverable (SIGINT + codex resume restores the conversation), but the pattern is hostile to unattended/overnight use — the agent's TUI silently freezes for tens of minutes whenever /side happens to hit the bad path, and the user has no visible signal that the sandbox loop is the cause.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗