Enter key stops responding after task completion in tmux (TUI input stuck)

Open 💬 5 comments Opened Feb 24, 2026 by probepark
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Bug Description

After a model turn completes (or after interrupting with Escape), the composer input field accepts text characters but Enter (submit) no longer responds. This happens consistently when running codex inside tmux.

Environment

  • codex-cli: 0.104.0 (Homebrew, aarch64-apple-darwin)
  • macOS 15.4 (arm64)
  • tmux 3.5a (inside byobu)
  • Terminal: iTerm2

Steps to Reproduce

  1. Launch codex inside a tmux session
  2. Send a prompt and let the model complete a turn
  3. Type a new prompt in the composer
  4. Press Enter → nothing happens
  5. Text remains in the prompt, turns:0 shown in statusbar

Expected

Enter should submit the text and trigger a new turn.

Actual

  • Characters are received and displayed in the composer
  • Enter key is completely ignored
  • tmux send-keys C-m also fails
  • Only workaround: Ctrl+C to kill the session and restart

Analysis

Looking at the source, codex enables the kitty keyboard enhancement protocol:

// tui.rs:73-79
PushKeyboardEnhancementFlags(
    KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES
        | KeyboardEnhancementFlags::REPORT_EVENT_TYPES
        | KeyboardEnhancementFlags::REPORT_ALTERNATE_KEYS
)

tmux has limited support for the kitty keyboard protocol. After a model turn completes, the terminal state may not properly reset the keyboard enhancement flags, causing the Enter key event (KeyCode::Enter with KeyModifiers::NONE) to not match the expected pattern in chat_composer.rs:1396.

The EventBroker pause/resume cycle during external command execution (with_restored) may also leave the crossterm EventStream in a state where key events are silently dropped.

Suggested Fix

  1. Add a fallback in handle_key_event that accepts raw \r (0x0d) as Enter even when keyboard enhancement reports don't match
  2. Or re-push keyboard enhancement flags after each turn completes
  3. Or detect stale input state and auto-recover

Workaround

Kill codex with Ctrl+C and restart the session.

View original on GitHub ↗

5 Comments

github-actions[bot] contributor · 6 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #11214
  • #12542
  • #12175

Powered by Codex Action

pavel-mironchik · 5 months ago

Stumbled upon a similar issue. This workaround helped:

tmux send-keys -t "$SESSION" -l -- 'My prompt to the Codex'
sleep 0.2
tmux send-keys -t "$SESSION" Enter
iqdoctor · 5 months ago

I investigated this on current main and found a concrete TUI-side failure mode that is consistent with the reported tmux symptom: TuiEventStream::poll_crossterm_event() resets the broker to Start on a crossterm Err/EOF, but the current code returns None to the outer app loop. The outer loop only listens on Some(event) = tui_events.next(), so one input-stream failure can leave the TUI process alive while keyboard input never recovers until process restart.

I prepared a fix branch that recreates the shared event source after a short backoff instead of terminating input handling, and adds regression coverage for both the Err and EOF recovery paths:
https://github.com/openai/codex/compare/main...strato-space:tui-input-recovery

While tracing adjacent code I also found a separate modal-lifecycle inconsistency in BottomPane::handle_paste(). That is tracked separately in #16192 so this issue can stay focused on the input-stream recovery bug.

I still could not open the PR from this environment because GitHub rejected CreatePullRequest for the current token, but the branch is public and ready for review.

ybratec · 4 months ago

Confirmed a related tmux/TUI stale-state symptom on current v0.118.0 on Linux.

Environment:

  • Codex CLI v0.118.0
  • Linux
  • tmux
  • launched via an omx wrapper, but the live TUI process is the normal /usr/bin/codex session

What happened:

  • a child subagent completed and the parent thread did wake up
  • the parent thread emitted its final assistant message
  • the rollout log for thread 019d61b9-5b70-78e2-9a11-56ebcfd12bba recorded task_complete at 2026-04-06T10:55:05.491Z
  • the Codex process stayed alive in tmux, but from the user side the TUI still looked hung/stale afterward

Important operator detail: the last interactive action before the stale state was switching back from the subagent to the main agent via /agent. I did not find a literal /agent token in the saved rollout, so that last step is from operator recollection rather than a logged command event, but the timing lines up with the subagent completion boundary.

So this does not look like a backend wait deadlock. The backend completed normally. It looks like another TUI/input/thread-switch state failure where the process stays alive but the interactive state does not recover cleanly after completion.

This feels adjacent to the issue here, but with a subagent/main-agent transition as the trigger.

PeaStew · 3 months ago
Stumbled upon a similar issue. This workaround helped: `` tmux send-keys -t "$SESSION" -l -- 'My prompt to the Codex' sleep 0.2 tmux send-keys -t "$SESSION" Enter ``

this works perfectly