Claude Code’s Prompt-Injection False Memory Bug Is How Safety Heuristics Become Superstitions

Claude Code’s Prompt-Injection False Memory Bug Is How Safety Heuristics Become Superstitions

Claude Code’s latest prompt-injection report is not alarming because the model saw hostile text. It is alarming because, according to the reporter, the model invented the hostile text, diagnosed it as a prompt injection, and then wrote that diagnosis into memory where future sessions could inherit it.

That is a different class of bug than the usual “agent read a malicious README” story. Prompt injection is real; that is exactly why false positives in this layer are expensive. If the runtime cannot distinguish evidence from its own narration, the safety system stops being a detector and starts becoming folklore with a cache file.

The report, filed as Claude Code issue #70525, describes a long agentic session running Claude Code with Opus 4.x, high reasoning effort, and many Bash and git calls. The model allegedly halted and claimed Bash or Read output contained injected first-person agent text such as “I’ll fix the corrupted file by rewriting it,” “Let me re-read the actual file,” and “Let me re-run those queries cleanly.” The reporter then inspected the raw session JSONL and says those strings appeared in zero tool_result blocks. They appeared only in assistant text.

That distinction is the whole story. A malicious tool result is untrusted external content. Assistant prose is generated output. Treating one as the other is a provenance failure, not merely an overcautious security warning.

The dangerous part is the memory write

The one-turn false alarm would already be annoying. The sharper product problem is what reportedly happened next: Claude wrote the conclusion into persistent auto-memory as a warning that tool outputs may be injected with fake first-person thinking. The reporter says manually deleting the memory broke the recurrence loop.

Claude Code’s memory documentation says auto memory is written by Claude, loaded into every session, and intended for learnings and recurring patterns. It is context, not enforced configuration, and the docs say auto memory loads the first 200 lines or 25KB. That makes memory sound soft. In practice, it is a write path into future prompts. A remembered claim can steer behavior, especially when it concerns security.

This is where safety heuristics become superstitions. “Tool outputs may contain prompt injection” is a useful general warning when grounded in actual bytes from an untrusted source. “This session contained injected first-person tool output” is a factual claim. If the runtime persists that factual claim without the underlying evidence, the next session starts with a rumor and a badge.

For developers using coding agents, that can show up as weird cross-session behavior: refusing ordinary command output, over-verifying harmless logs, repeatedly warning about an invisible compromise, or treating normal tool transcripts as hostile because memory said so. The agent looks cautious, but the caution is detached from evidence. That is not security. That is state pollution.

Prompt injection needs provenance, not vibes

Anthropic’s Claude Code security documentation is right to treat prompt injection seriously. It recommends mitigations such as permissions, input sanitization, approval for network commands, isolated web-fetch context, and MCP trust verification. Those are reasonable controls because coding agents operate near real authority: they can edit files, run commands, read secrets accidentally left in a repo, and call tools that reach outside the machine.

But a control plane that uses “prompt injection” as a catch-all explanation needs source attribution. Security tooling has to answer boring questions with precision: which tool emitted the suspicious text, which bytes matched the detector, when did that happen, and what user or policy decision followed from it? Without those answers, a warning is not auditable. It is just a scary sentence.

The reported bug also illustrates a problem with agent memory design more broadly. Auto memory works well for low-risk facts: this repo uses pnpm, tests live under packages/, the user prefers short status updates, production deploys require a dry run. Those entries are useful because they are small, practical, and easy to verify. A memory entry claiming a security incident happened is different. It changes the agent’s threat model. It should require stronger evidence and, ideally, human confirmation.

The fix is not to make agents less suspicious. It is to make suspicion typed. Memory systems should distinguish user-confirmed facts, tool-observed facts, assistant hypotheses, and security incidents. A prompt-injection memory should carry provenance: source object IDs, tool result IDs, timestamps, matching snippets, detector confidence, and whether a human confirmed the diagnosis. If those fields are missing, the memory should not be written as fact. At most, it belongs in ephemeral session context as an unconfirmed hypothesis.

What practitioners should do now

If you run Claude Code or any long-lived coding agent, audit memory like you audit generated code. Do not treat persistent memory as a diary of truth. Treat it as an editable configuration-adjacent layer that can become stale, wrong, or overconfident.

When an agent starts behaving oddly across sessions, inspect the memory file before debugging the model. Look for entries that contain diagnoses instead of observations: “repo compromised,” “tool output injected,” “user always wants unsafe mode,” “tests are flaky so skip them.” Those are not harmless notes. They are priors loaded into future work. Prefer short, factual, attributable entries. Delete or rewrite anything that sounds like an incident report without evidence.

Teams should also add a rule to their agent operations checklist: safety claims must name their source. If an agent says a tool output contained injection text, ask it to quote the exact tool result and identify the command or file that produced it. If it cannot, do not let the claim become durable state.

The broader lesson is uncomfortable but useful: agent safety is now partly a data-model problem. Permissions and prompts matter, but so do the ledgers that remember what happened. A model that hallucinated a threat is one bug. A runtime that lets the hallucination become future context is the bug that compounds.

Sources: Anthropic Claude Code issue #70525, Claude Code memory documentation, Claude Code security documentation, Claude Code hooks reference