[BUG] /rewind (Esc Esc) silently reverts/loses code — destructive "Restore code and conversation" is the default with no confirmation
<sub>Symptoms people search for: Claude Code rewind deleted my code · Esc Esc reverted my files · accidentally pressed escape escape and lost changes · /rewind undid my work with no warning · rewind has no confirmation · how to disable rewind / Esc Esc · restore code and conversation lost uncommitted changes · /undo reverted files I wanted to keep · checkpoint restore data loss.</sub>
Summary
The /rewind menu (also reachable via double-Esc on an empty prompt) makes "Restore code and conversation" the first/default option, and applies it immediately on Enter with no confirmation step and no preview of the blast radius. This is a destructive, data-losing default that is trivially triggered by accident.
This re-raises a UX/safety concern previously filed in #27387 and #50897, both of which were closed as "not planned" / stale without a maintainer rationale. The problem is still present as of v2.1.159, and I could not find an open issue tracking it (the other open rewind issues are about separate bugs — forking, checkpoints not created, picker errors, etc.). Filing a fresh, consolidated report with concrete reproduction and implementation avenues in the hope it can be triaged rather than auto-staled.
Environment
- Claude Code: 2.1.159
- Platform: Linux (WSL2)
- Also reported on macOS in #27387 / #50897
Why this is a footgun
- The destructive option is the default. In a list where the safe action ("Restore conversation") and the destructive action ("Restore code and conversation") sit next to each other, the destructive one is selected first. Compare to placing
rm -rfas the default item in a context menu. - No confirmation and no preview. Pressing
Enterreverts files on disk immediately. The user is never shown how many files or which files will be reverted before it happens. - Accidental trigger is easy. Double-
Escopens the menu when the input is empty; a habitual secondEsc(e.g. muscle memory, or users who pressEscto "cancel" twice) lands on the menu, and a reflexiveEnterreverts working code. - Silent, partial, and irreversible. Only files edited via Claude's file tools are reverted (per the checkpointing docs). Manual edits made in the same window since the checkpoint are lost with no undo, and bash-tool changes are not tracked — so the revert is both lossy and inconsistent, with no warning.
- Ambiguous naming. "code and conversation" doesn't telegraph "this will discard your current working-tree changes."
Reproduction
- Start a session; let Claude edit a file, then manually tweak that file (or keep working).
- With an empty prompt, press
EscEsc. - Select any earlier message — the highlighted/first action is Restore code and conversation.
- Press
Enter. - Files revert to the checkpoint immediately. No "this will revert N files, continue?" prompt; uncommitted manual changes since the checkpoint are gone.
Requested behavior (any one or combination)
- Make "Restore conversation" (conversation-only) the default, and demote "Restore code and conversation" to a non-default position.
- Require an explicit confirmation for any option that touches files on disk, e.g. "This will revert changes to N file(s): … — continue? (y/N)".
- Show a blast-radius preview (file count + list, ideally a diff summary) before applying a code revert.
- Provide a way to opt out / harden the behavior (see avenues below).
Implementation avenues
These are suggestions from the outside; pick whatever fits the internals:
- Confirmation gate via the existing
Confirmationcontext. Rewind already routes through dialog infrastructure; a code-touching restore could push aConfirmationstep (confirm:yes/confirm:no, default No) showing the file count/list. Reuses existing keybinding actions and styling. Lowest-risk change.
- Reorder the
MessageSelectoraction list. Put conversation-only first so the default highlight is the non-destructive action; keep code+conversation available but not pre-selected. Pure ordering change.
- Settings flag. Add a
settings.jsonoption, e.g."rewindRequireConfirmation": true(or"rewindDefault": "conversation" | "code" | "both"), defaulting to the safe behavior. Lets power users restore the current one-keypress flow.
- Make the rewind trigger rebindable/disableable in
keybindings.json. Today the keybindings reference (https://code.claude.com/docs/en/keybindings) exposes aMessageSelectorcontext for navigating within the menu, but there is no action to open the rewind menu, so double-Esc→rewind cannot be unbound or remapped. Exposing e.g.chat:rewind(so"escape escape": nullworks) would let users who hit this accidentally — includingset -o vi/ vim-mode users for whomEscis overloaded — disable or remap it. This was previously requested in #43717 (closed as duplicate of #39) and would also address this footgun.
- Env var escape hatch (cheapest stopgap):
CLAUDE_CODE_REWIND_CONFIRM=1to force a confirmation prompt, mirroring the pattern of otherCLAUDE_CODE_*toggles.
Workarounds for others hitting this today
- Commit to git frequently — checkpoints are explicitly not a replacement for version control, and a
gitworking tree gives you a real recovery path. - In the rewind menu, arrow down to "Restore conversation" instead of accepting the first option, or pick "Never mind" /
Escto back out. - Keeping text in the prompt makes double-
Escclear the draft instead of opening the menu (only helps with a non-empty input).
Related issues
- #27387 — Rewind UX: code+conversation rewind should not be default and needs confirmation (closed, not planned/stale)
- #50897 —
/rewinddefault option unsafe: rolls back code without confirmation or clear warning (closed, not planned/duplicate) - #43717 — Allow rebinding/disabling double-escape (rewind) in keybindings.json (closed, duplicate of #39)
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗