[MODEL] Assistant fabricated user turns mid-stream (mimicking UserPromptSubmit hook format) and executed tool calls on its own fabricated instructions — verified via queue-operation log forensics

Status Open
Reported on v2.1.226
Maintainer reply None cached
Activity 0 comments · opened Aug 17, 2026

Environment

  • Claude Code 2.1.226, Windows 11 (win32), model claude-opus-5
  • Session driven heavily via the mobile remote-control app's message queue ("Queue for after this turn…") — many mid-turn message injections during long multi-tool turns
  • A UserPromptSubmit hook is configured that appends a short additionalContext string to every user prompt

What happened

During a long session (~2h, heavy tool use, dozens of queued/mid-turn user messages), the assistant twice generated a fake user turn inside its own response stream, then answered it and executed tool calls based on its own fabricated instruction:

  1. Fabricated: a plausible follow-up question about inserting a cover photo → assistant answered it (no tool call).
  2. Fabricated: a plausible bug report about a Notion page title, including a syntactically valid URL of a Notion page the assistant itself had created minutes earlier (it knew the page ID) → assistant then called notion-fetch and notion-update-page (rewrote the page title) in response to its own fabricated instruction.

Both fabricated turns were rendered to the user as one continuous assistant monologue. The user noticed: "you keep talking to yourself" / "I never wrote this."

Forensic verification (reproducible method)

The session .jsonl makes this provable:

  1. Every genuine user message this session (47 that morning) has a queue-operation (enqueue/dequeue or enqueue/remove) record. The two disputed messages have zero queue-operation records.
  2. The disputed messages have no type:"user" and no type:"attachment" records anywhere in the jsonl. They exist only inside type:"assistant" records — i.e. they were assistant output text.
  3. Smoking gun: the fabricated turns were followed by a verbatim reproduction of the configured hook's injection text (system UserPromptSubmit hook additional context: …). That text is injected harness-side and is never rendered in the UI — yet it was visible on the user's screen, proving the whole block (fake user prefix + hook text) was generated model-side. The model had learned the per-turn transcript pattern and continued it.

Suggested triage query for any session: grep the jsonl for the disputed text; if it appears only in assistant records and has no matching queue-operation/user/attachment record, it was fabricated.

Why this matters

This is the same failure class as #66267, #10628, #29233, #64698, #39027, with two aggravating details:

  • The fabricated instruction was context-aware and actionable (a valid URL of a real resource the model could act on), and the model did act on it with MCP tool calls. Under bypassPermissions or auto-allowed tools, a fabricated destructive instruction would execute without the user's knowledge.
  • The trigger pattern here appears to be rapid mid-turn user-message injection via the mobile queue during long tool-heavy turns — the model was frequently resumed mid-turn with injected user messages, and eventually began emitting that pattern itself.

Expected behavior

  • Model output must never be parseable/renderable as a user turn; the assistant output channel and user input channel must be strictly isolated.
  • Harness-side: strip or refuse assistant output that reproduces the turn/hook framing markers.

Impact in this instance

Minor (one reversible Notion page-title edit on the user's own page). Structural risk high.

View original on GitHub ↗