[BUG] Cloud session: after a worker restart, the conversation was rewound to my last typed prompt and that prompt re-sent without my action
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
In a cloud session (Claude app, entrypoint: remote_cowork, Claude Code 2.1.281), the conversation jumped back about 45 minutes. A message I had sent 44 minutes earlier was then sent again with the same visible text. I did not press edit, retry, rewind or up-arrow, and I did not retype it. About 32 minutes of completed work, ending in a final approval question, dropped out of the active conversation. The entries are still in the transcript file, but on a dead branch.
What the transcript shows:
- The worker restarted at 23:14:30Z (see #96561). My last typed message was at 22:34:02Z. Everything after it was tool work plus one
AskUserQuestionanswered through the question card (atool_result). - After the restart and before 23:18:06Z, the new process very probably wrote this record:
``json``
{"type":"last-prompt","leafUuid":"<assistant entry before the 22:34 message>","explicit":true,"rewound":true,"sessionId":"<redacted>"}
- It has no
lastPrompt, so it was written before the new process's first prompt. - In 2.1.280 (the build I could inspect), the only code path that writes
rewound: trueis therewind_conversationcontrol-request handler. - That handler persists the anchor and returns the target's text as
prefillText. The CLI never generates this request itself, so it came from the connected client or the cloud bridge.
- At 23:18:06Z a new user entry arrived, parented to that anchor, with
promptSource: "sdk"andorigin: {"kind":"human"}. Its visible text was the same as the 22:34 message; only the timestamp reminder differed. This is the rewind-then-resend pattern.
Unlike #96388 (a replay injected by SessionStart:resume) and #89820 (an automatic "Continue" attached to a stale leaf), this transcript has a rewind_conversation record (last-prompt, rewound: true) and no "Continue" message.
Why the CLI didn't refuse it. The handler's stale-target check (stale_target / unseen_later_turn) only counts later user entries that are typed prompts, plus queued commands when last_seen_user_message_uuid is sent. It excludes tool_result entries, so an AskUserQuestion answer never counts as a later turn. After the 22:34 target, every user entry was a tool_result, so the check passes whether or not the client sent last_seen_user_message_uuid. An out-of-date client can therefore rewind over work the user took part in (answered questions, approvals) without being refused.
Which client sent it is unknown. It could have been:
- the Claude desktop app on Windows, where I answered a question card at about 23:17Z;
- the Claude iOS app, which was open in the background on the same session;
- the cloud relay itself.
The rewind record can only be placed between 23:14:30Z and 23:18:06Z, so it may have come before or after my click. Your server-side events for 23:14–23:19Z would show the sender.
What Should Happen?
- Clients shouldn't send
rewind_conversationplus a resend without an explicit user action. - The CLI's stale-target check should treat human answers delivered as
tool_result(AskUserQuestion answers) like typed turns. It should refuse a rewind that would discard one unlesslast_seen_user_message_uuidshows the client has seen it, and refuse whenlast_seen_user_message_uuidis null.
Error Messages/Logs
No error was shown. The UI jumped back, and the old message appeared again at the bottom as newly sent. Record shapes are shown above. I can share the session ID and relevant log excerpts privately with Anthropic staff (not in this thread).
Steps to Reproduce
I haven't reproduced this deliberately. It happened under these conditions:
- Start a cloud session from the Claude iOS app. Continue it on the Claude desktop app (Windows), leaving the iOS app open in the background.
- After your last typed message, let Claude work, and answer only through AskUserQuestion cards.
- Let the session sit idle on a pending question until the worker stops (about 4 minutes). Come back on the desktop app and answer the card (see #96561).
- By 23:18:06Z the conversation had been rewound to my last typed message, and that message had been re-sent. The rewind record was written after the 23:14:30Z restart, possibly before my click.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
Unknown
Claude Code Version
2.1.281 (cloud worker)
Platform
Anthropic API
Operating System
Other Linux (cloud worker); clients were the Claude iOS app and the Claude desktop app on Windows 11
Terminal/Shell
Other: the Claude app (cloud session), not a terminal
Additional Information
Companion issue: #96561. It covers the AskUserQuestion answer lost at the restart just before this. The rewind anchor here is the synthetic "No response requested." entry from that session's first restart.
Related:
- #89820 and #91632: turns parented to a stale leaf, orphaning later work.
- #96388: resume replays earlier user turns as if new.
- #66423: Desktop sends rewinds as message-id requests.