Status indicator can disappear after switching between active threads
Open
Nobody has claimed this yet.
bug
CLI
session
subagent
TUI
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.5k
- PR merge metrics
- PR metrics pending
Description
What version of Codex CLI is running?
- codex-cli rust-v0.148.0-alpha.1.
What subscription do you have?
- ChatGPT Pro 20x.
Which model were you using?
- gpt-5.6-sol.
What terminal emulator and version are you using (if applicable)?
- Alacritty inside tmux.
Codex doctor report
- Unavailable: all log recording is disabled for performance.
What issue are you seeing?
- Switching from an active thread to a sub-agent and back can permanently hide the active thread's status indicator even though the original turn is still running.
- The failure occurs when a thread switch overlaps the deferred status restoration window after streamed commentary finishes but before its stream queues become idle.
What steps can reproduce the bug?
- Start a long-running turn that produces streamed commentary.
- Wait until a commentary item finishes while its displayed stream is still draining.
- Open a running sub-agent before the active thread's status indicator reappears.
- Return to the main thread.
- Repeat the switch during this short drain window if the first attempt does not reproduce the issue.
- Observe that the main thread remains active but its status indicator can stay hidden.
What is the expected behavior?
- A thread switch preserves both the current status visibility and any pending request to restore the indicator after streaming becomes idle.
Additional information
ChatWidget::finalize_completed_assistant_messagesetspending_status_indicator_restorewhen a commentary stream has finalized but still needs restoration after its queues drain.App::select_agent_threadthen callsApp::store_active_thread_receiver, replaces the active widget withChatWidget::new_with_app_event, and replays the selected thread snapshot.ChatWidget::capture_thread_input_stateandThreadInputStatepreserve running/input state but omitcurrent_status, indicator visibility, andpending_status_indicator_restore.- Switching during the deferred window therefore destroys the only restore intent with the old
ChatWidget; switching back reconstructs a running widget with no event left to make the status visible. - Preserving those status fields in the per-thread snapshot and invoking
maybe_restore_status_indicator_after_stream_idleafter snapshot replay addresses the issue. - This report was organized with Codex CLI assistance from observed behavior and source inspection.
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
Trace ChatWidget::finalize_completed_assistant_message, App::select_agent_thread, App::store_active_thread_receiver, ChatWidget::capture_thread_input_state, and ThreadInputState. Reproduce switching during the stream-drain window, then inspect snapshot replay and maybe_restore_status_indicator_after_stream_idle. Done means the active thread retains status visibility and pending restoration across switches while its turn is still running.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100