Phantom user messages: text appears in transcript as user input that the user did not type

Status Open
Maintainer reply None cached
Activity 7 comments · opened May 13, 2026

Summary

Messages occasionally appear in the conversation transcript labeled as user input, but the user did not type them. The user has reported this happening multiple times across sessions. From the model's perspective these messages are indistinguishable from real user turns, which leads to the assistant acting on instructions the user never gave — and, when the user calls it out, the assistant has no way to verify and may incorrectly insist the user did type it.

Concrete instance (2026-05-13)

In a conversation about marketing strategy, the following sequence occurred:

  1. Assistant gave a ranked list of communities to target.
  2. User asked a clarifying question about terminology ("why 'gig'?").
  3. Assistant answered.
  4. A turn appeared in the transcript, labeled as user, with the text: "list the top 5 genre+city combos to target first"
  5. Assistant produced a long ranked list in response.
  6. User: "wait... did I tell you to list to 5 genre+city combos?"
  7. Assistant insisted: "Yes — your previous message was literally 'list the top 5 genre+city combos to target first'."
  8. User: "It was not! It's a bug. It must be your suggestion or something. I did NOT write this, and it's not the first time."

The user is confident they did not type or submit that message. The phrasing is also notably model-like (concise, structured, action-oriented) compared to the user's other turns in the same conversation.

Hypothesized causes

  • Suggested follow-up prompt chip in the Claude Code UI being auto-submitted by a misclick, stray Enter, or focus issue
  • <user-prompt-submit-hook> or similar hook inserting text that the model sees as user input
  • Slash-command expansion appearing in the user-turn slot
  • Terminal paste artifact / autocomplete inserting cached text
  • An actual bug in input handling

Impact

  1. Assistant performs unrequested work (in this case, generated a long ranked list the user did not ask for).
  2. When challenged, assistant cannot distinguish a real user message from an injected one, so it may double down and gaslight the user.
  3. User loses trust in the conversation history.

Suggested mitigations

  • If suggested-prompt chips can auto-submit, add a confirmation step or move from one-click submit to two-step.
  • If hooks can write into the user-turn slot, surface them visibly (e.g., distinct rendering) so both user and model can see it was injected.
  • Provide a transcript view that distinguishes typed-by-user vs. injected-by-system turns, so the user can verify what was actually sent.

Environment

  • Claude Code CLI (terminal)
  • macOS Darwin 24.6.0
  • Model: Claude Opus 4.7 (1M context)

Reported via Claude Code by user mbtmbt@gmail.com.

View original on GitHub ↗

6 Comments

github-actions[bot] · 3 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/14269
  2. https://github.com/anthropics/claude-code/issues/46500
  3. https://github.com/anthropics/claude-code/issues/51703

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

mbtmbt · 3 months ago

Prior instance found in transcript history (2026-05-10)

After searching this user's prior Claude Code transcripts, here is one clear earlier instance of the same pattern. The user (mbtmbt) reviewed a prior session's history with the assistant — and did not recognize one of the quoted messages as something they typed.

Session: b6424441-417e-42a2-bf1a-b65d1c1aa529.jsonl (Claude Code v2.1.132, CLI entrypoint, project /Users/mbt/events, branch main)

Phantom message (appeared as user turn):

[2026-05-10T08:18:23.939Z] USER: disable rec refresh during wikidata outage

Context: This message appeared in the transcript ~76 seconds after the assistant's previous output. The assistant immediately treated it as a directive and made three Edit tool calls across shared/alerts.py, web/routes/recommendations.py, and web/recheck.py. The user interrupted ~63 seconds later. (This is consistent with a chip/suggested-prompt firing — the directive is concise, action-oriented, fits the conversational context perfectly, and the assistant acted on it before the user typed any further input.)

The denial (next session, 2026-05-10T08:24:29 UTC):
The user resumed work, asked the assistant to summarize what had happened. The assistant rendered a detailed chain-of-reasoning with timestamped quotes including the phantom message. The user replied:

strange. I don't recall saying it.

Why this is strong evidence:

  • The user reviewed a timestamped transcript and could not recognize their own alleged message.
  • The "message" caused immediate, unprompted code editing — high impact.
  • This is the same project/user/CLI as the issue's primary instance, suggesting it's not a one-off.
  • The phantom-message phrasing is concise and command-shaped, which fits the suggested-prompt-chip hypothesis better than the typo/paste-artifact hypothesis.

Combined picture across both incidents:

  • 2026-05-10: phantom directive → immediate code edits, user had to interrupt
  • 2026-05-13: phantom request → assistant generated a long unrequested response, user had to call it out

Both incidents resulted in real work being done on instructions the user did not give.

eggnstone · 2 months ago

This is a serious security issue.
I can confirm similar behavior.
Why is this not been acted on?

EZOLOG · 2 months ago

Confirming this on a very different setup — so it is not macOS/Opus-4.7-specific:

  • Claude Code v2.1.170, model claude-opus-4-8, Windows 11 (build 26200)
  • Antigravity IDE (VS Code-based) integrated terminal, shell via MSYS/Git Bash

Same phenomenon: a phantom "user" turn the user never sent, which the assistant then acted on and later insisted the user had said. It does NOT appear as user input (type:last-prompt) in the local .jsonl — it first appears as assistant output. (Filed separately as #66878; closing that as a duplicate of this.)

What may help: I was able to isolate a reproduction trigger from the local session log. In every occurrence, three conditions coincided immediately before the phantom message:

  1. A heavy / very slow turn — the assistant had just run a WebSearch and produced a long response; generation stalled for 6+ minutes.
  2. The user interrupted that stalled turn (recorded as [Request interrupted by user]).
  3. While waiting, the user typed one or more additional messages, which queued up (consecutive queue-operation events in the log).

Immediately after that, the phantom user message appeared. Hypothesis: while generation is blocked for a long time, the interrupt signal races with queued user inputs, corrupting input-ingestion / context-assembly ordering, so the assistant ends up responding to a non-existent (or mis-associated) input.

Possibly related: the triage bot linked #56880, which attributes a transcript-message replacement to the claude-in-chrome MCP channel — may be worth checking whether an active MCP input channel is involved.

Daniel-Josef-S · 1 month ago

Unexplained chat message (OPML/RSS feed content) appeared in my session — not sent by me

Description

During an active chat session with Claude (date: 2026-07-02), a message appeared in the conversation history as if sent by me, which I definitely did not write or submit. I had been working with Claude on a software project (a Home Assistant integration) up to that point; the conversation was purely technical. Without any action on my part, the following message suddenly showed up in the transcript:

sag mir mal was ich hier kaufen soll: <opml><body><outline text="AliExpress Angebote" title="AliExpress Angebote"><outline text="🔥90%OFF🔥Neue Silikon-Ohrstöpsel zum Schlafen, wiederverwendbare, geräuschreduzierende Ohrstöpsel, super weiche, bequeme Ohrstöpsel zum Schlafen, Reisen und Studieren" title="🔥90%OFF🔥Neue Silikon-Ohrstöpsel zum Schlafen, wiederverwendbare, geräuschreduzierende Ohrstöpsel, super weiche, bequeme Ohrstöpsel zum Schlafen, Reisen und Studieren" type="rss" xmlUrl="https://de.aliexpress.com/item/1005006131921934.html" htmlUrl="https://de.aliexpress.com/item/1005006131921934.html"/><outline text="52 Stück Silikon-Nagelfeile, Buntes Nagelpolierset, Doppelseitiges Nagel-Schleifpapier, Einweg-Maniküre-Werkzeuge Für Zuhause Und Salon" title="52 Stück Silikon-Nagelfeile, Buntes Nagelpolierset, Doppelseitiges Nagel-Schleifpapier, Einweg-Maniküre-Werkzeuge Für Zuhause Und Salon" type="rss" xmlUrl="https://de.aliexpress.com/item/1005008393041424.html" htmlUrl="https://de.aliexpress.com/item/1005008393041424.html"/></outline></body></opml>

Notably, the content has the structure of an OPML/RSS feed export (nested <outline> tags, type="rss", xmlUrl/htmlUrl attributes), this is not a format I would normally type or paste into a chat.

What I've already checked

  • My account's login/session history: no unknown or additional logins found.
  • The message was unrelated in both topic and format to my actual conversation (software development).

Steps to reproduce

Not reliably reproducible. Sequence of events leading up to the issue:

  1. Had an active, ongoing chat session with Claude, working on a software development task (unrelated to shopping/e-commerce).
  2. Sent several normal chat messages/tool interactions as part of that task.
  3. Compacted session without any additions.
  4. At some point, without me typing or pasting anything, the OPML/RSS content described above appeared in the conversation as a message attributed to me.
  5. I did not knowingly copy, paste, or import any RSS/OPML data at any point in this session.

Context / Environment

  • Operating system: Windows 11 Pro
  • Approximate time: 2026-07-02, during an active chat session
  • Appeared in Desktop Client v1.17377.1 / Claude Code Sonnet 5
julia98percent · 1 month ago

Same bug, reproduced in the VSCode extension (not just TUI) — with transcript-level forensic evidence.

SUMMARY
A user message that the user never wrote appeared in the model's context mid-turn, was rendered in the UI as a user bubble, and was later concatenated (with a literal "user" role label) into the middle of the user's next real message. The phantom text has NO user record in the session transcript and exists nowhere on disk.

ENVIRONMENT

  • Claude Code VSCode extension (native), macOS (Darwin 25.5.0)
  • Session: 9eccd453-9e0b-4b09-a1df-fc29e0487700
  • 3 concurrent sessions were active on the same project at the time; one transcript is ~64MB
  • Model: claude-fable-5

EVIDENCE (transcript: ~/.claude/projects/<project>/<session-id>.jsonl, lines 819-826 and 844)

  1. Assistant text turn ends at 08:59:01.623Z (uuid fe514e91).
  2. 400ms later (08:59:02.025Z) a new assistant tool_use (ToolSearch) begins with parentUuid = fe514e91 — assistant→assistant chaining, NO user record in between. Yet the model's context contained a full "user request" (asking to check github.com/segmentio/evergreen compatibility), which the assistant then acted on for ~2 minutes (WebFetch, Bash, npm registry checks — all read-only).
  3. At 09:02:11.742Z (line 844) a genuine user record contains: the user's real short message + a literal "user" label + the entire phantom text verbatim + the user's closing sentence ("this isn't what I wrote?"). User confirms they neither wrote nor copy-pasted it — the client concatenated it into their outgoing message.
  4. The phantom text exists nowhere else on disk: searched all project transcripts, history.jsonl, paste-cache (empty), ide/, todos/, shell-snapshots — 0 hits. In-memory only.
  5. Content style is clearly LLM-generated: English discourse marker ("That reminds me —") mid-Korean sentence; contextually plausible but fabricated facts (referenced a teammate recommendation and a "last week" conversation that never happened).

SUSPECTED CAUSE
The prompt-suggestion feature (ghost-text placeholder suggesting the user's likely next message, tab-to-accept). An unaccepted suggestion appears to have been (a) injected into the API request as if sent, without creating a transcript user record, (b) rendered as a user bubble, and (c) left in the input buffer so it got spliced into the next real message with its role label. The user has previously seen similar unsent "user ~~" suggestion text appended at the end of conversations in other sessions.

IMPACT
This time only read-only actions resulted (public GitHub fetch, local grep, npm registry query). But the same mechanism could trigger state-changing actions (file edits, commits, MCP writes) from a request the user never made. The injection happens below the transcript layer, so it is invisible in the recorded history.

REPRO
Not deterministic. Conditions at the time: long-running session (~2.3MB transcript), 3 concurrent sessions on one project, VSCode extension, heavy MCP (Notion) usage earlier in the session. An earlier harness glitch occurred in the same session ("The previous response failed to produce a valid tool call. Please retry the tool call now." with no preceding failed call visible).

Environment Info

  • Platform: darwin
  • Version: 2.1.185
  • Feedback ID: e43d5f42-31d5-450f-bfed-90fe265b7fdc

Showing cached comments. Read the full discussion on GitHub ↗