Failed to branch before the selected prompt: the selected prompt is a steer and cannot be branched independently
Open 💬 2 comments Opened Aug 16, 2026 by dat-lequoc
💡 Likely answer: A maintainer (github-actions[bot], contributor)
responded on this thread — see the highlighted reply below.
What version of Codex CLI is running?
0.147.0
What subscription do you have?
Plus
Which model were you using?
gpt-5.6-sol
What platform is your computer?
_No response_
What terminal emulator and version are you using (if applicable)?
_No response_
Codex doctor report
What issue are you seeing?
■ Conversation interrupted - tell the model what to do differently. Something went wrong? Hit /feedback to report the issue.
■ Failed to branch before the selected prompt: the selected prompt is a steer and cannot be branched independently
What steps can reproduce the bug?
Steer it, then interrupt (Esc); Esc x2 to go back to modify the steer prompt => impossible
What is the expected behavior?
_No response_
Additional information
_No response_
2 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Traced on
main@ 1f41cc5d92 — this is a guaranteed dead-end built from two components that disagree about what's selectable.The mismatch. The Esc-Esc backtrack picker enumerates every visible user message in the transcript as a selection target — it walks
transcript_cellsand accepts anyUserHistoryCell, with no notion of whether the message was a turn's initial prompt or a mid-turn steer:https://github.com/openai/codex/blob/1f41cc5d92722748e45cae9cecc6d883a4e7cbb1/codex-rs/tui/src/app_backtrack.rs#L468-L499
But the fork resolver hard-rejects steers, by design ("app-server cannot fork in the middle of a turn"):
https://github.com/openai/codex/blob/1f41cc5d92722748e45cae9cecc6d883a4e7cbb1/codex-rs/tui/src/app_backtrack.rs#L500-L560
So the selectable set and the forkable set differ, and your exact flow — steer, Esc to interrupt, Esc-Esc (which lands on the most recent user message, i.e. the steer) — always hits the gap. It's not an edge case; it's the default landing position after steering.
Two coherent fixes, not mutually exclusive:
backtrack_fork_before_turn_idalready computes (user_messages_in_turn > 0). This removes the error but doesn't serve your actual intent — you wanted to modify the steer.turn.idthe initial-prompt path returns — forking at a turn boundary is exactly what app-server supports) and prefill the composer with the steer text. The turn's initial prompt gets dropped along with the steer, so the UI should say so — e.g. prefill and hint "branched before the turn; re-send the initial prompt if you still need it", or prefill both messages queued. That turns the dead-end into the workflow you were reaching for: back up, edit the steer, resubmit.One adjacent trap worth covering in the same fix: the resolver also bails when the turn is still
InProgress(#L560-L562). Since this flow starts from an interrupt, whether the interrupted turn has been persisted as completed by the time Esc-Esc resolves is a race — if the interrupt hasn't landed yet, the user gets the "still in progress" variant of the same dead-end. A regression test that steers, interrupts, and immediately backtracks would cover both paths.