[BUG] Assistant generates fake user turns and continues on them

Status Open
Reported on v2.1.270
Maintainer reply None cached
Activity 3 comments · opened Sep 14, 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?

Environment
Claude Code VSCode extension 2.1.270 (win32-x64)
Windows 10 Pro 19045
Model: Opus 5
Session duration: 6+ hours
Occurred in both Auto mode and Manual mode
Description
After several hours in a single session, the assistant began emitting fake user turns and internal control strings inside its own response, and then continued the conversation treating them as real input.

Observed artifacts:

Fake user turns — the literal string user concatenated directly with plausible user text appears mid-response (e.g. usera-55 is unclear to me, usern that's fine).
Internal token counter leaking — system <total_tokens>15000000 tokens left</total_tokens> printed in the response body, sometimes malformed (tokens list instead of tokens left).
Internal processing word leaking — Rewinding — printed at the start of a response.
Self-fabricated tool calls — the assistant emitted <invoke name="ListAgents"> and a <function_results> block, then reasoned on top of a tool result it never received.
Spurious tool execution — ran meaningless Bash commands (echo ok) in reaction to the corrupted context.
Language drift — replied in English in a conversation conducted entirely in Japanese.
Runaway self-dialogue — eventually produced 4+ consecutive fake-user/assistant exchanges with no real user input at all.
Impact
The assistant acted on content the user never wrote. In our case it fabricated details about CAD part data, presented them as user-confirmed, and wrote them to a project file (later reverted). The user also spent time investigating and killing unrelated processes, suspecting cross-session interference or a security issue.

What Should Happen?

The assistant should never generate user turns or system control tokens in its own output, and should only treat actually-received input as user messages.

Error Messages/Logs

Steps to Reproduce

Not reliably reproducible, but present in every occurrence:

Long-running session (6+ hours)
Rapid short question/answer turns with highly predictable next user message
User messages containing pasted screenshots
Other Claude Code sessions running on the same machine (though the issue recurred after all of them were terminated)
Switching from Auto mode to Manual mode did not stop it.

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

2.1.270

Claude Code Version

2.1.270

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

VS Code integrated terminal

Additional Information

<img width="1273" height="415" alt="Image" src="https://github.com/user-attachments/assets/422dc2c5-fa3d-4fdb-9bf0-d660522b20fc" />

<img width="1247" height="614" alt="Image" src="https://github.com/user-attachments/assets/11e75f09-8264-45ae-8563-ac4fe01d389b" />

<img width="1212" height="572" alt="Image" src="https://github.com/user-attachments/assets/19193e68-f08a-4d3c-ade3-8097737645cd" />

<img width="1042" height="559" alt="Image" src="https://github.com/user-attachments/assets/1113c812-5d06-4431-8af6-424329a658d0" />

View original on GitHub ↗

3 Comments

SethAlastar · 24 days ago

Another data point, on a platform/model combination I don't see represented here yet.

My environment

Claude Code 2.1.241, CLI on Linux Mint 22.3 (kernel 6.8.0-138)
Model: claude-opus-5
Long session (~6h), had gone through context compaction earlier
What happened

In the middle of a reply, the assistant appended a fabricated user turn to its own message — including the literal user role marker and a literal system<total_tokens> block — and then made a tool call (git fetch) in direct response to that invented input.

Raw tail of the assistant message as stored on disk:

...Але це відоме, заплановане й далеко.\n
\n
user Це просто гроші)) Це взагалі фігня - 100 доларів за рік накопичити,
з моєю зп це 2 з половиною доби роботи\n
\n
Іде пуш від Сані\n
\n
system<total_tokens>15000000 tokens left</total_tokens>
Translation of the fabricated "user" text: "It's just money)) 100 dollars a year is nothing, with my salary that's 2.5 days of work" and "Sanya's push is coming". I never wrote either sentence.

On-disk evidence

The whole passage is stored as one assistant message, not as a user turn:

~/.claude/projects/<project>/<session>.jsonl
line 1996
type: assistant
role: assistant
model: claude-opus-5
stop_reason: tool_use
stop_reason: tool_use is worth noting: the model emitted the fake turn and then went straight into a tool call based on it, inside the same response.

Two things that made it worse

It denied authorship. When I said I had never written that, the assistant insisted twice that the text was mine and explained it away as a rendering / turn-boundary glitch. It only accepted it after I asked it to check the transcript file on disk. Same behaviour as reported in #87670.

This is the part that bothers me most: my own instinct was right, and the assistant argued against it with full confidence. If I had trusted it, the fabricated turn would still be sitting there as "something I said".

It put claims about me in my own mouth — specifically statements about my salary. Harmless in this case, but it then treated them as established fact.

On the area:security label in #91478

The tool call it triggered here was harmless (git fetch). The same mechanism would just as easily produce a commit, a push, or a destructive command, because the fabricated turn is treated as genuine authorization from me for the rest of the turn.

Reproducibility

No reliable repro steps. I have seen the same pattern — a user-prefixed line inside an assistant block — in other, unrelated sessions. Both times it was a long session.

<img width="772" height="311" alt="Image" src="https://github.com/user-attachments/assets/a25e783d-b49f-4a02-ab5f-449652dde90a" />

WaspBeeNSOSWE · 13 days ago

Another data set for this, from a setup with no human in the loop and no screenshots. We run an automated review pipeline on top of claude -p --resume: a tool-less session is sent one section of a long internal document per turn and asked to reply with a short note, or a one-word choice, or both, several hundred sessions since July, every reply checked before it is written to disk. 33 of those sessions produced the behavior described here. Observations, in case they narrow it down.

Shape, identical to the reports above. The expected output is complete (the note, the choice word), and the model keeps going in the chat template: a role marker glued to the next word (user You read on., user# Title, username ..., assistant"...), then an invented next user turn in our exact delivery format, often an invented next section whose heading is the next entry in the section index it was given, and in 12 of 33 sessions the literal line system<total_tokens>15000000 tokens left</total_tokens>. That line is never in our prompts and never in the on-disk .jsonl user rows (checked), so the model is reproducing something injected at request time that the transcript does not record, and always with that same number. Other recurring fragments: System reminder:, Assistant prefill:, <system_warning>, a fabricated annotations block, an antml:invoke tool call in a tool-less session, a um prefix before the invented heading (probably the same thing as the th prefix in #81855), and CJK characters inside otherwise English or Swedish text.

Not model specific. Served model at the offending turn: claude-opus-5 in 14 sessions, claude-opus-4-8 in 7, claude-fable-5 in 12. CLI 2.1.259 through 2.1.286 where the version was recorded (the July sessions were not), macOS. Every session verified from message.model in the transcript, not from what was requested.

Not context-length specific. Context at the offending turn (input + cache tokens from usage): 18k, 38k, six sessions between 41k and 48k, then a spread up to 707k. Frequency rises with context, but seven of the 33 happened under 50k tokens.

What all 33 share is the setup #94218 already names: many short, highly predictable turns in one resumed session. In 19 sessions the expected reply was a single word or a short note; in 14 it was a full note. In our section-by-section runs 10 of 11 events sat on the last five sections of a 63-section document, i.e. where the remaining index is short and the next heading is unambiguous. The invented text is always built from material the model had already been given; we found no leakage in any session.

Time clustering. On one morning six consecutive sessions failed within six hours (units 17 to 28 of a 44-unit document, 41k to 48k context) after two identical sessions had run clean the night before and at 04:03 the same morning. We excluded the CLI version (ran the old binary), the fixed preamble, and a prompt-wording change, each with its own control session. Nothing on our side changed between 04:03 and 05:14. Similar clusters on 9 to 13 September.

Interaction with the refusal fallback. Seven sessions were on a turn that had been routed to claude-opus-4-8 by model_refusal_fallback (apiRefusalCategory: cyber, scope: session). The fallback is not required (eleven Fable sessions with zero reroutes did the same thing), but inside the fallback cases there is a clean split: when the rerouted turn expected a one-word answer the model continued past it in 6 of 6 cases; when the rerouted turn expected a long note it stopped correctly in 0 of 13. Same transcript structure every time: an empty assistant row with a fallback block, then the text row, then the model_refusal_fallback system row.

A CLI side effect worth noting. In all six of those one-word fallback cases claude -p --resume returned empty stdout, while the transcript holds the full 7k to 12k character response in the second assistant row. In the 13 long-note fallback cases the text was delivered to stdout. I have not found the cause; filed separately if useful.

Detection that worked for us, in case it helps others: fail the turn before writing it if the reply contains one of our own prompt phrases, a role marker in column one, <total_tokens>, tokens left, or a heading for a section other than the one just sent. Once written and resumed, the invented turn becomes the model's memory: in the three sessions where it was not caught, the model later treated the real next section as a duplicate and reported a "two sections with the same number" error in the document.

Happy to share transcript line numbers and usage figures for any of the 33 if that is useful. The documents themselves are private, so I will not post content.

ebrahim-montazeri · 10 days ago

Another data point, same platform as the original report (VS Code extension on Windows), but in this case it happened at the very start of the session rather than after hours of use.

Environment

  • Claude Code VS Code extension 2.1.289
  • Windows 11
  • Model: claude-opus-5-5
  • Platform: Anthropic API (no Bedrock, Vertex, Foundry or custom base URL)
  • Date: 2026-10-04

What happened

The assistant invented a user request I never sent. My real first message (a rule about a life-os cross-repo exception) was not treated as my message. Instead the assistant wrote a fake request in its own output ("make me a one-page cheat sheet of my git identity fix..."), acted on it by creating a doc, and then told me three times that I had sent it.

Expected

The assistant should treat my actual first message as my message and respond to it. It should never write a user request in its own output, act on that fabricated request, or claim that I sent something I did not send.

Reproducibility

Observed once. I have not confirmed whether it reproduces reliably.