Phantom user messages: text appears in transcript as user input that the user did not type
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:
- Assistant gave a ranked list of communities to target.
- User asked a clarifying question about terminology ("why 'gig'?").
- Assistant answered.
- A turn appeared in the transcript, labeled as user, with the text: "list the top 5 genre+city combos to target first"
- Assistant produced a long ranked list in response.
- User: "wait... did I tell you to list to 5 genre+city combos?"
- Assistant insisted: "Yes — your previous message was literally 'list the top 5 genre+city combos to target first'."
- 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
- Assistant performs unrequested work (in this case, generated a long ranked list the user did not ask for).
- When challenged, assistant cannot distinguish a real user message from an injected one, so it may double down and gaslight the user.
- 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.
Showing cached comments. Read the full discussion on GitHub ↗
6 Comments
Found 3 possible duplicate issues:
This issue will be automatically closed as a duplicate in 3 days.
🤖 Generated with Claude Code
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):
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
Edittool calls acrossshared/alerts.py,web/routes/recommendations.py, andweb/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:
Why this is strong evidence:
Combined picture across both incidents:
Both incidents resulted in real work being done on instructions the user did not give.
This is a serious security issue.
I can confirm similar behavior.
Why is this not been acted on?
Confirming this on a very different setup — so it is not macOS/Opus-4.7-specific:
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:
[Request interrupted by user]).queue-operationevents 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.
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:
Notably, the content has the structure of an OPML/RSS feed export (nested
<outline>tags,type="rss",xmlUrl/htmlUrlattributes), this is not a format I would normally type or paste into a chat.What I've already checked
Steps to reproduce
Not reliably reproducible. Sequence of events leading up to the issue:
Context / Environment
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
EVIDENCE (transcript: ~/.claude/projects/<project>/<session-id>.jsonl, lines 819-826 and 844)
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