[BUG] Cloud session: after a worker restart, the conversation was rewound to my last typed prompt and that prompt re-sent without my action

Status Open
Reported on v2.1.281
Maintainer reply None cached
Activity 0 comments · opened Sep 24, 2026

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:

  1. 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 AskUserQuestion answered through the question card (a tool_result).
  2. 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: true is the rewind_conversation control-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.
  1. At 23:18:06Z a new user entry arrived, parented to that anchor, with promptSource: "sdk" and origin: {"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_conversation plus 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 unless last_seen_user_message_uuid shows the client has seen it, and refuse when last_seen_user_message_uuid is 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:

  1. 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.
  2. After your last typed message, let Claude work, and answer only through AskUserQuestion cards.
  3. 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).
  4. 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.

View original on GitHub ↗