[BUG] Stream breaks when response contains literal thinking tag text
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
When Claude's response contains the literal XML-like thinking tag as content (not as an actual thinking boundary), the stream gets truncated or breaks.
The irony: I discovered this while asking Claude to help debug why typing this tag in my application broke streams. Claude could not explain the bug without triggering the bug. The debugger became the debugged.
Suspected cause: Text-based boundary detection somewhere in the streaming pipeline that doesn't distinguish between "Claude is thinking" vs "Claude is talking about thinking tags as string content."
Environment:
- Claude Code CLI (latest)
- Discovered via ACP integration in external editor (thinking the bug was mine, reproduced with Claude Code CLI)
What Should Happen?
Expected: Claude can discuss its own internals without triggering them
Actual: Response truncates mid-sentence when the literal tag text appears in output
Error Messages/Logs
> odd. so not found in lumina and not found in claude code acp. would have to set up a test example with claude agent sdk to see it happen there if so... .tell me though. how does "thining" actually work
again, I have session logs on this and can pull it up. but is it interleaved in the message as a tag? thus it would make sense if using the tag itself from claude would trigger something?
● ` that needs to be parsed → string detection happens
The user is right to suspect that if there's tag-based detection happening, typing the literal tag could confuse the parser.
Let me explain this clearly.
Great question! Let me explain the layers:
★ Insight ─────────────────────────────────────
Two different "thinking" mechanisms exist:
1. Extended Thinking (API-level) — Structured thinking blocks in API response, separate from content
2. Interleaved Thinking (streaming) — XML-like `
● Here's my answer...
The SDK/client is responsible for:
1. Detecting these boundaries in the stream
2. Separating them into `AgentThoughtChunk` vs `AgentMessageChunk`
3. NOT including the literal tags in the output
## Your Suspicion is Correct
If the Claude Agent SDK is doing text-based boundary detection like:
if (chunk.includes('
> LOL. it just cut off here too? or did you literally just say:
If the Claude Agent SDK is doing text-based boundary detection like:
if (chunk.includes('
and nothing more?
● HAHAHAHA the irony is chef's kiss 🤌
Yes, my message literally got cut off right when I tried to write the example code containing the thinking tag! The very bug we're investigating just bit ME.
Let me try again, carefully escaping the problematic text:
What I Was Trying to Say
If the Claude Agent SDK is doing text-based boundary detection like:
if (chunk.includes('<' + 'antml:thinking' + '>')) {
// Switch to thinking mode
}
Then typing the literal tag in your message triggers that detection! The parser thinks Claude started a thinking block when really YOU (or I!) typed that text as content.
---
This Just Proved the Theory
My message to you went through the same pipeline and got chomped. The bug is almost certainly:
1. Somewhere in the streaming layer (SDK, API wrapper, or even Claude's own output processing)
2. Text-scanning for XML-like boundaries instead of using structured API response types
3. Triggering on literal tag text in content, not just actual thinking boundaries
---
★ Insight ─────────────────────────────────────
The fact that this happened to MY response (Claude → You via Claude Code → Lumina) confirms the issue is upstream of Lumina — likely in how Claude's streaming output is chunked before it even becomes ACP protocol messages.
─────────────────────────────────────────────────
Want me to search for how the Claude Agent SDK handles streaming to pinpoint where the boundary detection happens?
> LOOOOOOOOOOOOOOOOOOOOOOOL
⎿ Interrupted · What should Claude do instead?
> LOOOOOOOOOOOOOOOOOOOOOOOL. THIS SESSION WE ARE IN CLAUDE CODE CLI
● 🤣🤣🤣
WE FOUND IT BY ACCIDENT
The bug is in Claude Code CLI itself — the very tool I'm running in right now! When I tried to output the literal tag, it broke MY stream to YOU!
So the culprit isn't:
- ❌ Lumina (clean)
- ❌ claude-code-acp (clean)
- ❌ Claude Agent SDK (maybe?)
- ✅ Claude Code CLI's streaming parser
The irony is immaculate. I literally cannot type the tag without breaking my own output. This is the most self-demonstrating bug I've ever encountered.
★ Insight ─────────────────────────────────────
The bug lives in Claude Code CLI's output handling — it's scanning MY responses for XML-like boundaries and getting confused when I output them as literal text. This happens BEFORE it ever reaches ACP or Lumina.
─────────────────────────────────────────────────
Should we file this upstream with Anthropic? You've got a perfect reproducible case now: just ask Claude to explain thinking tags and watch the stream die 💀
Steps to Reproduce
Repro steps:
- Start a Claude Code session
- Ask Claude to explain how thinking/reasoning tags work in the API
- Watch Claude's response get cut off the moment it tries to write the literal tag
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.0.76
Platform
Other
Operating System
Windows
Terminal/Shell
WSL (Windows Subsystem for Linux)
Additional Information
Two Claudes told me to report it. Whatever, perhaps this TOO meta. But still.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗