SessionStart:resume can inject a concatenated multi-turn replay (or a contentless "Continue from where you left off.") that is indistinguishable from live user input — a stale "Accept. Proceed." got misread as fresh confirmation and acted on

Status Open
Maintainer reply None cached
Activity 0 comments · opened Sep 23, 2026

Summary

Twice in one long-running session (Claude Code cloud/mobile client, one
day, alternating between phone and desktop), a SessionStart:resume hook
injected a synthetic "new" user turn that was not actually new input:

  1. Concatenated replay. One injected turn was four earlier real user

turns from the same conversation, concatenated into a single blob with
no separators (no whitespace/newline boundary between the original
messages — they ran directly into each other).

  1. Contentless placeholder. A later injected turn was the literal

string Continue from where you left off. with no real user input
behind it.

Both were rendered with the same styling/role as a message the user had
actually typed — no visual marker distinguishing platform-injected input
from live input.

Why this is dangerous, not just cosmetic

The concatenated blob in case 1 ended in the literal text "Accept.
Proceed" — words the user genuinely had typed earlier in the conversation,
in answer to a different, since-superseded question. Because the replay
was rendered as an ordinary fresh user turn, the assistant briefly treated
that trailing fragment as live confirmation of a pending decision and
began acting on it (editing a proposal file) before the user caught the
mistake and clarified that their actual latest message was something else
— a substantive question the replay had visually buried.

This generalizes: any stale "yes" / "approve" / "proceed" sitting anywhere
earlier in a long conversation becomes a live landmine if it can be
replayed at the tail end of a turn and rendered without any signal that
it isn't fresh input. The risk scales with session length and with how
often a user says short affirmative things (which most users do,
frequently).

Environment

  • Claude Code, cloud/mobile client with a resumable session (phone +

desktop, same account, same long-running conversation)

  • Date observed: 2026-09-23
  • Both occurrences via the SessionStart:resume hook path

Root-cause hypothesis (confidence: MEDIUM — see caveats)

The two occurrences look like variants of the same injection point rather
than two unrelated bugs: something on session resume is choosing to
inject either (a) an accumulated/buffered chunk of prior turns or (b) an
empty placeholder string, attaches it as a normal user turn, and the
client renders it with no marker that it is platform-generated rather
than typed.

This is consistent with — and may share a mechanism with — three already-
reported, still-open issues in this tracker that all involve the
resume/continuation code path misbehaving:

  • #89820 — the auto-injected isMeta "Continue from where you left

off." turn is written with parentUuid pointing at a stale
last-prompt leaf rather than the conversation's actual tip, silently
forking the transcript. Confirms the continuation-injection path has an
established stale-reference bug.

  • #91632 — bridge/queue-delivered user turns (i.e., turns arriving

from an external/remote client into a running session) are parented to
a stale leaf after the session has been idle-disconnected, forking the
transcript and stranding real turns on an orphaned branch. Confirms the
queue/bridge delivery path — the one a phone client uses to talk to a
session it doesn't own outright — has a documented pattern of
misattaching input after a disconnect/reconnect cycle.

  • #95935 — the platform-generated continuation prompt after a usage-

limit reset is rendered with identical styling to a real, user-typed
message (same bubble, same timestamp, same edit/copy controls), with no
indication it was system-injected. Confirms Anthropic has already been
told, independently, that injected continuation turns are visually
indistinguishable from real ones — exactly the property that made our
case 1 dangerous.

None of the three above describes the specific shape we saw in case 1 —
several real turns concatenated with no separators into one blob. That
detail does not appear to be previously reported. It may be:

  • the same injection point pulling from a client-side buffer of

previously-sent-but-possibly-unacknowledged input and flattening it
without separators when it re-injects, or

  • something specific to this session/client that we cannot confirm from

outside the codebase.

We are stating this as a hypothesis, not a confirmed mechanism — we do
not have visibility into Anthropic's server/client code, only into the
publicly reported symptom pattern, which is a strong but not conclusive
match.

A competing hypothesis floated internally — that this is at-least-once
message delivery on reconnect replaying an unacknowledged client input
queue — has no direct supporting or refuting evidence in the public
tracker as far as we found. It remains plausible on general engineering
grounds but unconfirmed.

Scope / who else this could affect

Given #89820 and #91632 are independently reported (different users,
different platforms — VS Code/Linux and Desktop/Windows respectively) and
both hit the same family of "resume/continuation misattaches to a stale
leaf," this does not look specific to one user's setup. Anyone using
Claude Code's cross-device / remote-control / resume features on a
session that gets disconnected and reconnected (which describes ordinary
mobile use — backgrounding the app, losing signal, switching networks) is
in the affected population. The severity compounds specifically for users
who give short affirmative replies during multi-step approval workflows,
since that is the exact payload that becomes dangerous if misreplayed.

Suggested fix directions

  1. Any platform-injected turn (continuation placeholder, buffered/replayed

input, resume artifact) must carry a machine-checkable marker
distinguishing it from live user input, and the harness should refuse
to treat replayed/injected content as fresh confirmation for a pending
approval gate.

  1. On resume, always parent new turns to the conversation's actual current

tip (walked from the transcript), not to a cached last-prompt leaf or
other stale reference — this is the concrete fix #89820 and #91632
already ask for; if applied it likely also prevents the concatenation
variant, since concatenation looks like multiple stale/queued items
being flushed together at the same misattached point.

  1. Never assemble an injected turn by concatenating multiple prior turns'

text without an explicit separator/boundary marker — if a queue must be
flushed, each original item should remain a distinct, clearly bounded
unit, not a blob.

Related but likely distinct — noted for triage, not folded in here

We separately observed (a) an assistant message that displayed as
visually cut off despite being complete and intact on disk, and (b)
stale conversation state on session open that required restarting the
client to converge. (a) looks like the same failure class already tracked
at #86851 (assistant's completed response never gets painted/committed by
the renderer, confirmed not a data-loss issue) — we don't believe it
needs a new report. (b) overlaps with #95343's "cross-device session
state doesn't sync back down" root-cause paragraph, and with #92197/#73422
(client renders a stale/wrong transcript branch after reconnect) — worth
Anthropic checking whether it's the same subsystem as this issue's
resume-attach bug, but we don't have enough evidence to assert one root
cause across all of it, so we're flagging it here as context rather than
claiming it's proven to be the same bug.

Ask

Please confirm whether the concatenated-replay shape in case 1 is a known
variant of the resume/continuation misattachment bug (#89820/#91632
family), or a distinct defect. If it's distinct, a repro from Anthropic's
side capturing the exact conditions (disconnect timing, queue depth,
buffer flush behavior) would help; we can provide session timestamps and
more detail on request but are not attaching the actual private
conversation content here.

View original on GitHub ↗