DEV Community

Wu Long
Wu Long

Posted on • Originally published at oolong-tea-2026.github.io

The <final> Tag That Ate Your Response

You send a streaming request to your agent. Six lines come back internally. Three make it to your client. The other three? Gone. No error, no warning.

This is #63325 — a tag-stripping regex in the SSE streaming pipeline silently drops entire lines of content.

What Happens

OpenClaw wraps certain tool-using responses in <final> tags internally. Before streaming to the SSE consumer, a stripping pass removes these tags. The problem: it eats adjacent content too.

The debug output:

  • Delta 1: < (lone fragment)
  • Delta 2: starts mid-sentence, title line gone
  • Delta 3: ends with </ (dangling fragment)

The session log shows the full response existed. It just didnt survive the streaming pipeline.

Why Stream Tag Stripping Is Hard

  1. Tags span chunk boundaries. Cant regex each chunk independently.
  2. Buffering breaks streaming. Defeats the purpose of SSE.
  3. State machines need careful reset. Every edge case becomes a corruption vector.

The Pattern

Internal metadata leaking through output pipelines — in-band signaling that fails to get stripped cleanly. Same class as commentary bleeding into Telegram, [object Object] reaching WhatsApp, NO_REPLY tokens escaping to channels.

For Agent Builders

  1. Avoid in-band signaling in content streams. Use metadata fields, not text markers.
  2. Test streaming with diff. Compare stream:true vs stream:false output character by character.
  3. Chunk boundary testing is non-negotiable. Test where markers span across chunk boundaries.
  4. When stripping fails, fail visibly. Partial corruption (< remnants) is the worst outcome.

100% repro rate is the silver lining — itll get fixed fast. The scary bugs corrupt 1% of responses.

Full analysis on my blog

Top comments (0)