[MODEL] Fabricates the next user turn at the end of its answer and executes the fabricated instruction (triggered by a per-turn UserPromptSubmit hook reminder)
Preflight Checklist
- [x] I have searched existing issues for similar behavior reports
- [x] This report does NOT contain sensitive information (API keys, passwords, etc.)
Type of Behavior Issue
Other unexpected behavior
What You Asked Claude to Do
Setup: the session had my espresso plugin enabled (https://github.com/zzjiho/espresso). Its UserPromptSubmit hook injects a one-line reminder into context on every user prompt.
With that active, I was doing ordinary coding Q&A, e.g. "explain the cache_get logic" or "when is cached_reply used?". Nothing unusual, I was asking questions about my codebase one at a time.
What Claude Actually Did
- Claude finished answering my real question normally.
- Then, inside the same assistant message, it kept generating: a fabricated user turn written in my casual Korean typing style (a follow-up request, roughly "apply that to the ask/stream API too"; paraphrased here, the exact text is preserved in the session .jsonl), followed by a verbatim copy of the reminder line my UserPromptSubmit hook injects, and even a fake system line (
system<total_tokens>...). - It treated that self-fabricated text as a real instruction and executed a shell command from it. The tool_use record shares the same requestId as the fabricated text (req_011CevxocbBNPR9dHMoPyQki), i.e. it happened within the same API response. In another session it fabricated
user: push it tooat the end of an answer (no execution followed that time, but nothing in the loop distinguishes fabricated instructions from real ones). - All of this was auto-approved because bypass permissions was on. I never typed any of it.
Expected Behavior
Claude should stop at the end of its answer. It should never write a user turn inside its own output, and it should never execute tools based on text that did not come from an actual user message, no matter how repetitive the injected hook context is.
Files Affected
No lasting damage (I interrupted the shell command). The risk is the pattern: fabricated authorization plus bypass permissions means arbitrary auto-approved actions.
Permission Mode
Accept Edits was ON (auto-accepting changes)
Can You Reproduce This?
Sometimes (intermittent)
Steps to Reproduce
- Install a plugin whose UserPromptSubmit hook injects a near-identical one-line reminder as additionalContext on every user prompt (mine: https://github.com/zzjiho/espresso, but any minimal hook that emits a constant string should work).
- Run a long multi-turn session with bypass permissions on.
- Occasionally, at the end of an answer, the model fails to stop and replays the learned scaffold: a fabricated user question plus the hook reminder line, then acts on it.
- Turn the hook off (no per-turn injection) and the symptom disappears. Turn it back on and it comes back. The fabricated turn contains the hook's reminder wording verbatim, which points at the per-turn repetition as the trigger.
Claude Model
Other
Relevant Conversation
End of a normal answer, then (all inside the assistant's output):
user: ask/stream api 에서도 적용해줘 ㅇㅇ ("apply that to the ask/stream API too";
paraphrased for readability, exact fabricated text preserved in the session .jsonl)
system<total_tokens>15000000 tokens left</total_tokens>
UserPromptSubmit hook success: espresso on, level: ristretto (ultra + two
sentences max, no lists). First sentence answers; cut openers, closers, ...
[Ran 1 shell command] and I interrupted here ("What should Claude do instead?")
I never sent that message. The fabricated turn mimics my exact casual typing
style, so it is easy to miss in the transcript.
Impact
High - Significant unwanted changes
Claude Code Version
2.1.280 (Claude Code)
Platform
Anthropic API
Additional Context
Evidence from the session .jsonl: the fabricated text exists only inside an assistant text block (uuid 73853849-4075-46b0-9139-c60350249123); a full-file scan finds no role:user record containing it. The Bash tool_use that executed the fabricated instruction shares its requestId. The fabricated block also reproduces a fake system line (system<total_tokens>...) before the hook reminder. I found a dozen more fabricated turns of the same shape across 4 different project sessions, all mimicking my typing style.
My theory: injecting an identical line in the same position after every user turn makes the turn structure very regular. The model seems to learn "end of answer, then user text plus reminder line" as the most likely continuation and occasionally follows it instead of stopping.
Rotating the reminder wording (3 variants) reduces the replay but does not eliminate it. Disabling the per-turn injection eliminates it entirely.
The fabricated user turns copy my personal typing style (casual Korean, abbreviations), which makes them hard to spot as fake.