TUI: Ctrl+C while editing a previous message appends thread_rolled_back and hides the message
Summary
In the interactive Codex CLI TUI, pressing Ctrl+C while editing a previous message appears to be handled as a thread rollback instead of a harmless edit cancellation. The selected previous message disappears from the TUI/resumed conversation, while the original message is still physically present in the session JSONL.
Version
Originally observed while using codex-cli 0.142.0.
After updating, local codex --version currently reports codex-cli 0.142.5; The display bugs still exist, but I have not yet confirmed the bug still reproduces from start on 0.142.5.
Reproduction Steps
- Start or resume an interactive Codex CLI TUI session.
- Press
Escto select a previous user message. - Press
Enterto edit that previous message. - Press
Ctrl+Cto quit/cancel the edit. - Observe the TUI transcript or resume/fork the session.
Actual Behavior
The selected previous message disappears from the TUI transcript / reconstructed conversation.
Expected Behavior
Canceling edit mode should discard only the temporary edit buffer. The original previous message should remain visible and the logical conversation should remain unchanged.
JSONL Investigation
The original message is still physically present in the saved session file under ~/.codex/sessions/.../*.jsonl, so the message content is not deleted from disk.
However, after each reproduction, the JSONL has an appended event like:
{"type":"event_msg","payload":{"type":"thread_rolled_back","num_turns":1}}
In my affected session, each thread_rolled_back event corresponded to one disappeared previous message. Removing those rollback events from a backed-up JSONL session file restored the missing messages when resuming the session.
Hypothesis
Ctrl+C from previous-message edit mode is taking the rollback path instead of the edit-cancel path. This likely affects the reconstructed logical thread, not just the current TUI display, because the rollback event is replayed from JSONL on resume/fork.
3 Comments
I reproduced the same underlying failure in the macOS Codex Desktop surface embedded in ChatGPT, so this is not limited to the CLI TUI.
Environment:
Sequence:
The content was recoverable from the local rollout JSONL. Around the failure, the durable log contains:
The earlier completed prompt and assistant final response remain physically present in the same JSONL, but Desktop reconstruction hides them. Codex thread search could still find the thread, and direct JSONL inspection recovered the missing messages. Forking the affected thread from the app API failed twice with a generic error, while creating a fresh recovery thread worked.
This looks like the Desktop edit-after-interrupt path emits rollback events with the same destructive replay semantics reported here. The two consecutive
thread_rolled_backevents may explain why more than only the edited turn disappeared.Expected: stopping a turn and editing/resubmitting its message should replace only the intended turn. It must not hide the preceding completed turn, and duplicate rollback events should not be emitted.
Confirmed temporary recovery workaround for the Desktop reproduction I described above.
The affected messages were still present in the rollout JSONL. The only records making them disappear during reconstruction were the two erroneous
thread_rolled_backevents immediately following the interrupted/edited turn.What worked for me:
~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl.thread_rolled_backrecords.Example, using the exact timestamps from my affected file as selectors:
Do not copy those timestamps literally: first inspect your own JSONL and target only the erroneous rollback records associated with the disappearance. Removing legitimate rollback events can restore turns the user intentionally rewound.
I performed the replacement while Codex Desktop was still running and the affected thread was idle; it worked, and a subsequent thread read returned both the previously completed proposal turn and the later interrupted user message. Closing Codex before replacement is likely safer because an active writer could otherwise append to the old inode. Keep the backup until the recovered thread has been verified.
This is only a recovery workaround. The underlying bug remains the duplicate/destructive rollback emission and replay behavior.
It happened for me when editing a message on mobile twice