Codex CLI 0.153.0: interrupted paginated thread makes resume/fork TUI hang on macOS
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Summary
After a Codex CLI session froze during an active model turn, the OS process was gone and no subprocess or file lock remained, but the paginated-history database still marked the turn as inProgress.
After that:
codex resume <thread-id>reported that the session was not found, even though its state DB row and rollout file both existed.codex fork <thread-id>created a valid fork record, then the full-screen TUI became unresponsive and the terminal window had to be closed.- Disabling the configured Playwright and Node REPL MCP servers did not fix the fork hang.
This started after upgrading to Codex CLI 0.153.0.
Environment
- Codex CLI:
0.153.0 - Installation: Homebrew cask/native arm64 binary
- OS: macOS arm64
- Terminal: Apple Terminal 470.2
- Model:
gpt-5.6-sol - History mode:
paginated - Authentication: ChatGPT
- Memory: 8 GB
Reproduction
- Start a sufficiently long CLI thread that produces multiple command execution items.
- Interrupt or force-close the terminal while the model is still streaming a turn.
- Confirm that no Codex subprocess or writer lock for the affected thread remains.
- Try:
codex resume <thread-id> - The CLI may report that the session was not found even though the thread exists in
state_5.sqliteand its rollout file exists. - Try:
codex fork <thread-id> - A fork is created, but the full-screen TUI becomes unresponsive and must be force-closed.
Sanitized diagnostics
The affected source thread had:
history_mode: paginated
rollout size: 2,111,722 bytes
rollout records: 301
rollout JSONL validation: OK
projection next_rollout_byte_offset: 2,111,722
projection next_rollout_ordinal: 301
thread turn status: inProgress
turn error_json: null
items: 75
commandExecution items: 33
commandExecution JSON total: 598,591 bytes
largest commandExecution item: 291,901 bytes
Important distinctions:
- The projection cursor exactly matched the rollout EOF, so this is not the cursor-behind or offset-mismatch failure described in #38792.
- SQLite
quick_checkpassed. - Every persisted custom tool call had a matching tool-call output.
- The rollout had
task_started, but notask_complete; it ended after a reasoning item. - No OS process, open file descriptor, or writer lock remained for the source thread.
- Network connectivity was healthy.
The fork command created a new rollout whose session_meta correctly contained a redacted source thread under forked_from_id. The new rollout contained only four records:
session_meta
thread_settings_applied
message
turn_aborted
The forked turn was stored as interrupted.
The fork-process logs showed:
thread/fork request received
fork session initialized
thread/started emitted with targeted_connections=0
WebSocket connection succeeded
warmup request succeeded and produced last_model_response_id
(no ERROR log)
TUI remained unresponsive until the terminal window was closed
The issue reproduced after these local MCP servers were disabled:
[mcp_servers.playwright]
enabled = false
[mcp_servers.node_repl]
enabled = false
An optional Figma MCP server was omitted during startup and was not required.
Expected behavior
On startup/resume/fork, Codex should detect that an inProgress turn has no live process or writer lock and reconcile it to an interrupted/aborted state.
A valid paginated thread whose projection cursor is caught up to the rollout should be resumable or forkable without freezing the TUI. If recovery is impossible, the CLI should return an actionable error instead of a misleading “session not found” response or an indefinitely unresponsive TUI.
Actual behavior
The source turn remains logically active after its process has disappeared. Resume cannot resolve it correctly, and fork creates a child thread but fails to attach/render it in the TUI.
Possible regression area
Codex CLI 0.153.0 changed several relevant paths:
- TUI history now renders complete patches, background-terminal input, and individual completed commands.
- Rollout compression includes shared histories.
- Resume/fork handling changed for compressed/shared rollouts.
- TUI reconnection behavior changed around app-server disconnects.
This may be an interaction between stale active-turn reconciliation, shared/paginated fork reconstruction, and TUI history hydration for a thread containing a relatively large command-execution item.
Related issues
- #37577: paginated history reconstructs completed turns as interrupted.
- #38792: projection cursor corruption causes resume to open at the first turn.
- #42387: Desktop history stops rendering after a mid-turn crash.
This report differs because the projection cursor is fully caught up and internally consistent, the source turn remains inProgress without a live process, and both CLI resume and fork fail before a usable TUI is attached.
No customer names, conversation contents, credentials, raw thread IDs, or sensitive logs are included.
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 by reproducing the failure with codex resume <thread-id> and codex fork <thread-id> using a paginated thread interrupted during a model turn. Trace stale inProgress reconciliation, paginated/shared rollout reconstruction, and TUI history hydration from startup through fork. Done means an orphaned turn is reconciled or reported clearly, and a valid thread can resume or fork without an unresponsive TUI.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100