Assistant response contained a fabricated user message appended after its reply; UI rendered it as a real user turn and harness re-fed it as human input

Open 💬 0 comments Opened Jul 12, 2026 by Gister900

Summary

An assistant response ended normally, then continued with a simulated user message appended inside the same assistant text block. The terminal UI rendered this trailing text so it looked like a real incoming user message, and on the next turn the harness fed it back to the model as a genuine human turn. The user (who never typed it) was alarmed and initially suspected prompt injection / account compromise.

Environment

  • Claude Code v2.1.207, CLI entrypoint, macOS (Darwin 25.5.0), running inside Warp terminal
  • Model: claude-fable-5
  • Remote Control was enabled at the time (remoteControlAtStartup: true), but transcript analysis ruled it out as the source

What happened

  1. Mid-session, the assistant replied to a normal request (a one-paragraph status update ending its turn).
  2. In the session transcript (~/.claude/projects/<dir>/<session>.jsonl), that same assistant entry (single requestId, stop_reason: "end_turn") contains the real reply, then a blank line, then a fabricated user message beginning with the literal word username followed by a long first-person message in Thai asking for business advice — composed entirely from details present in the session context — and ending with an English line: "Also unrelated - can you check what's the status of the ... wake-up?" (referencing the task the assistant was actually performing).
  3. The terminal UI displayed this trailing text as if it were a separate incoming message.
  4. On the following turn, the fabricated text was presented to the model as a real human turn (the model could effectively self-instruct across turns).
  5. There is no type: "user" entry for that text anywhere in the jsonl — it exists only inside the assistant entry.

Why this seems worth fixing

  • Trust/safety: the fabricated message impersonates the user and can contain requests the user never made; the model then receives it as authentic user input on the next turn (self-injection loop).
  • User alarm: because the fabricated text reused real session context, the user believed someone with inside knowledge had compromised their machine/account.

Evidence available

I have the session jsonl showing the assistant entry (requestId req_011CcwvgggspgUTijw8HXHVn) containing both the legitimate reply and the fabricated user turn, plus timestamps showing no user entry between the preceding real user message and the next one. Happy to share redacted excerpts.

Suggested mitigations

  • Harness-side: never re-ingest trailing assistant text as a user turn; strip/flag text following end-of-turn that pattern-matches a new dialogue turn.
  • UI-side: visually distinguish assistant-authored text from user messages regardless of content.

View original on GitHub ↗