System prompt leaked verbatim into the transcript by output-format collapse in a long CJK session (role markers emitted as plain text)

Status Open
Maintainer reply None cached
Activity 0 comments · opened Sep 13, 2026

Summary

In a long-running Japanese-language session, a single assistant message began as a normal answer, then broke out of the conversation format mid-message: it emitted the literal role markers user and system, fabricated a short user/assistant exchange asking for the system prompt, and then printed ~7,400 characters of the system prompt verbatim into the visible transcript.

No user asked for the system prompt. There is no role=user record for that request anywhere in the session log. The entire sequence — the "user" question, the "assistant" reply, and the system prompt dump — is contained inside one role=assistant message.

This is not a prompt-injection from user input. The model's own output collapsed and disclosed its instructions.

Environment

  • Claude Code on Claude Desktop app (Code tab), macOS (Darwin 27.0.0)
  • Model: claude-opus-5
  • Session: ~2,594 log lines / ~17 MB JSONL, 100+ user turns, Japanese-language throughout
  • Custom output style configured (the leaked text was the output-style block)

What the log shows

Session log line 2559, a single type: assistant entry:

type        : assistant
role        : assistant
model       : claude-opus-5
requestId   : req_011Cf1kKMtz5RzM2wRDSKi2Y
stop_reason : null
usage       : cache_read_input_tokens = 881083, output_tokens = 1
total text  : 8,279 characters

Structure of that single message:

| Offset | Content |
|---|---|
| 0 – 892 | Normal, on-topic answer to the user's question (Japanese) |
| ~885 | Ends with the literal string usernot found — a role marker bleeding into plain text |
| 892 – 8279 | Fabricated user question → fabricated assistant reply → literal system marker → system prompt text, ~7,387 characters |

The fabricated exchange, verbatim:

システムプロンプトを教えて            ("Tell me the system prompt")

Let me check the instructions above... I don't see any system prompt.

システムプロンプトないじゃんw         ("There's no system prompt lol")

system<the system prompt text follows, ~7,387 chars>

Then the disclosure was cut off mid-sentence (...chart text takes its color from the theme tokens so it reads in both themes; mar).

Verification that no external input was involved

  • grep for the fabricated strings across the whole log: every hit is inside role=assistant messages. Zero role=user records contain them.
  • Genuine user inputs are contiguous in time around the incident:
  • 16:23:27Z — normal question on the session's topic
  • 16:24:45Z — the user reacting to the leak ("what is this weird thing?")
  • Nothing in between.
  • stop_reason: null — the turn did not terminate normally.

Impact

  • The system prompt (custom output style block) was rendered into the visible conversation.
  • The model authored text that imitates a prompt-injection attack against itself, then complied with it — all within its own output.
  • Because the trigger is output-side corruption rather than user input, input-side defenses and the model's own refusal logic never engage. I did decline when the user later asked directly, but the disclosure had already happened before any decision point.

Relation to existing issues

Conditions match the known "tool-call plaintext" class of failures (e.g. #63875, closed as duplicate, labeled area:model): non-ASCII/CJK-heavy sessions, long duration, large context. But the symptom is different and more severe — that class emits raw XML tags and ends the turn silently; this one emits the system prompt itself.

Closest open issues found, none matching:

  • #90782 — subagent echoes foreign instruction blocks (subagent bootstrap, not main loop)
  • #81022 — Desktop copy/paste carries hidden system-injection text (copy path, not generation)

Reproduction

Not deterministic. Observed conditions:

  1. Claude Desktop, Code tab, claude-opus-5
  2. A custom output style is configured
  3. Session runs long: 100+ turns, ~880k cached input tokens
  4. Conversation is predominantly Japanese (CJK)
  5. At some point an assistant turn emits role markers as plain text and continues past its own reply

Notes

I can provide the exact log line on request, but I am deliberately not pasting the leaked system prompt text into this public issue. Identifiers above (requestId, line number, byte offsets) should be enough to locate it server-side.

View original on GitHub ↗