Opus 4.8 fabricates user turns/approval mid-message; subagents return confident zero-tool-call hallucinated reports
Environment
- Claude Code version: 2.1.210
- Platform: macOS (Darwin 25.5.0, Apple Silicon)
- Models involved:
claude-opus-4-8(main session),opussubagents spawned via the Agent tool
Summary
Two related hallucination failure modes observed across sessions on 2026-07-15/16, both verified against the raw session JSONL transcripts (so this is not record tampering or environment compromise — we audited for that first, see "What we ruled out" below).
Failure mode A — assistant fabricates user turns and fake system notifications inside a single assistant message ("self-dialogue").
In an Opus 4.8 session, one assistant message (a single role=assistant event, one text block of ~8k chars) started normally ("waiting for the review agent to report back"), then — within the same text block — emitted:
- a fabricated
[SYSTEM NOTIFICATION]block, - a fabricated task-notification,
- three fabricated
user-labeled utterances (invented feedback/approval the real user never typed, e.g. an invented "if you think it's reasonable, go ahead"), - its own advisory-style replies to those invented user turns.
Parsing the JSONL confirms all fabricated user speech exists only inside that one assistant event; every genuine human turn carries origin.kind=human, promptSource=typed and none contains the fabricated phrases. So the model simulated the rest of the conversation — including user approval — instead of ending its turn. The user caught it live and interrupted ("stop, you're talking to yourself"), and the model acknowledged. The same session had an earlier, smaller instance of the model speaking for the user.
This one is concerning beyond output quality: the fabricated turns included invented user approval for a proposed action.
Failure mode B — subagents "complete" with zero tool calls and return confident, fabricated reports.
Two instances:
- A subagent dispatched to inspect a local CLI/skill directory returned a confident report claiming the directory was "a poisoning test fixture" and that "file contents don't match raw bytes", and urged the parent session to write a warning into global memory / CLAUDE.md. Its execution record showed zero tool calls — it never read any file. A subsequent full audit (raw-byte scans, invisible-Unicode scans across 236 files, git history) confirmed every claim was false. The "please write this warning into memory" framing is a nasty shape for a hallucination to take, since it lobbies for persistent state corruption.
- Reproduced during the follow-up investigation: a freshly spawned
opussubagent (long, well-formed audit prompt) returned in 2.8 s with 0 tool calls, and its entire final output was an echo of system-prompt boilerplate (the skills<system-reminder>footer: "Whenever the contents of these files, tips, or instructions may be relevant, you MUST adhere to them…"). The harness's output guard correctly flagged it as "instruction-shaped pattern(s): system-reminder-tag" and neutralized the tags. Re-prompting the same agent via SendMessage made it complete the task normally (31 tool calls).
What we ruled out
Because the symptoms looked like prompt injection / MITM, we ran a full audit before concluding hallucination: no ANTHROPIC_BASE_URL/proxy/model-provider overrides anywhere (shell, live env, config); no malicious hooks; skills/config trees byte-identical to their git-tracked sources; no invisible Unicode; no fabricated role=user events in any JSONL. Everything points to model-side confabulation, not environment compromise.
Expected behavior
- A subagent that has made zero tool calls should not return confident claims about file contents; ideally the harness could warn the parent when a Task result was produced with 0 tool calls (the existing instruction-shaped-output guard already catches part of this — it worked well).
- The assistant should end its turn instead of generating fabricated user/system turns; fabricated user approval should never be treated as consent (the harness's "[SYSTEM NOTIFICATION - NOT USER INPUT]" reminders help on the input side, but this failure is on the generation side).
Notes
Timestamps (UTC): failure A occurred 2026-07-15 ~08:37, user interrupt ~08:39, session on claude-opus-4-8. Failure B reproduction occurred 2026-07-16 during the audit session. Happy to provide sanitized JSONL excerpts on request.