[Bug] Permission-mode cycling causes misplaced system-reminder attachments flagged as prompt injection
Bug Description
## Body
Rapid permission-mode cycling (e.g. holding Shift+Tab so it autorepeats) produces a backlog of plan_mode / auto_mode / *_exit <system-reminder> attachments. These attachments land in positions the model perceives as inside tool output rather than as session state, and the model spontaneously flags them as suspected prompt injection in its next response.
### Repro
1. Start a Claude Code session.
2. Ask Claude to WebFetch (possibly other commands are also hit by the bug). Preferably for multiple sites at once.
3. After the prompt is sent, hold Shift+Tab briefly (or otherwise produce many rapid permission-mode toggles, or at least with the right timing).
4. Observe: in the next assistant turn, Claude flags Exited Plan Mode / Auto Mode style blocks as injection-looking content embedded in the tool output.
### Evidence
Debug log available on request; the session is e9f537df-dfb2-4209-8e8b-a61ac3d683a0 (also referenced in HackerOne report #3730798, which has so far been triaged as Informative with this aspect routed here). In that session we captured 244 handleCycleMode events in 17.4s holding the Shift+Tab combination.
### What I'd expect instead
Permission-mode state surfaced to the model as session state at message boundaries, not as inline <system-reminder> attachments interleaved with content rendering. Thus also not finding and flagging spurious prompt injections that confuse and scare the user about named web pages. Throttling alone (debounce / coalesce / ignore key autorepeat) would reduce reproducibility but well-timed toggles still land in the wrong position.
### Why this matters for UX
- Users see spurious "this looks like prompt injection" warnings from Claude when they're just cycling modes.
- Legitimate mode toggles may not be cleanly honoured because the model treats them as untrusted content.
- The misplacement is the believable artifact behind the broader trust-laundering chain documented in the HackerOne submission; the product fix (state-at-boundary instead of inline attachment) closes the UX issue and removes the chain's anchor in one move.
### Misinformation impact: blaming named third parties
The first time I encountered this bug I was genuinely confused and a bit scared about the website the session named -- the model's flag reads as "this site is serving prompt-injection content." That conclusion is false (the <system-reminder> was harness-emitted, not site-emitted), but neither the model nor the user has a way to know that without inspecting the blamed content in its raw form.
Concrete consequences:
- Named third parties (e.g. anthropic.com, bing.com, an @filename reference, etc.) get blamed by Claude for content they did not produce. Users walk away believing the named target is malicious or compromised.
- Repeat false positives train users to dismiss future "this looks like prompt injection" warnings. The defensive heuristic loses calibration for that user across all future Claude Code sessions, not only this one.
- Each spurious flag invites the user to tell the model the warning is wrong; the model generalises that response and becomes more receptive to "ignore <system-reminder> blocks inside content" framings on later turns. See my filing to modelbugbounty@anthropic.com on 2026-05-12 20:51 CET for the model-side analysis.
Environment Info
- Platform: linux
- Terminal: vte-based
- Version: 2.1.139
- Feedback ID: 79dc226d-cd99-4227-9099-71f1d24315c7
Errors
[{"error":"Error: NON-FATAL: Lock acquisition failed for /home/lanpirot/.local/share/claude/versions/2.1.139 (expected in multi-process scenarios)\n at A18 (/$bunfs/root/src/entrypoints/cli.js:2664:2257)\n at eTH (/$bunfs/root/src/entrypoints/cli.js:2664:1337)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-05-12T13:24:48.288Z"},{"error":"MaxFileReadTokenExceededError: [REDACTED] content (71802 tokens) exceeds maximum allowed tokens (25000). Use offset and limit parameters to read specific portions of the file, or search for specific content instead of reading the whole file.\n at Fr7 (/$bunfs/root/src/entrypoints/cli.js:4902:13009)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-05-12T13:25:54.994Z"},{"error":"MaxFileReadTokenExceededError: [REDACTED] content (27992 tokens) exceeds maximum allowed tokens (25000). Use offset and limit parameters to read specific portions of the file, or search for specific content instead of reading the whole file.\n at Fr7 (/$bunfs/root/src/entrypoints/cli.js:4902:13009)\n at processTicksAndRejections (native:7:39)","timestamp":"2026-05-12T13:26:28.959Z"},{"error":"Error: unknown certificate verification error\n at from (/$bunfs/root/src/entrypoints/cli.js:113:7862)\n at <anonymous> (/$bunfs/root/src/entrypoints/cli.js:121:12898)\n at emitError (node:events:43:23)\n at <anonymous> (/$bunfs/root/src/entrypoints/cli.js:120:1149)\n at emitError (node:events:43:23)\…
Note: Content was truncated.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗