[BUG] Corrupted final JSONL entry after streaming fallback ("Content block is not a input_json block")
Resolved 💬 5 comments Opened Feb 10, 2026 by icycrystal4 Closed Mar 12, 2026
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?
In one session, the final line of the session JSONL is corrupted after a streaming error/fallback.
Observed behavior:
- Debug log reports:
- Streaming stall detected: 72.7s gap between events (stall # 1)
- Error streaming, falling back to non-streaming mode: Content block is not a input_json block
- The final JSONL record is syntactically valid JSON, but semantically corrupted:
- message is no longer a normal object (role/content/model/...)
- instead it contains thousands of numeric keys ("0", "1", ...) as character fragments
- message.content becomes an empty array
- Previous line is normal, final line is corrupted.
This breaks downstream consumers that parse Claude Code session JSONL.
What Should Happen?
On streaming failure, fallback to non-streaming should still produce a normal, schema-consistent assistant message record in JSONL.
Specifically:
- message should remain a standard message object (role, content, model, stop_reason, etc.), not a character-indexed map.
- The final JSONL entry should be structurally consistent with prior entries.
- No data corruption should occur in persisted session logs, even when Content block is not a input_json block is encountered.
Error Messages/Logs
Debug log:
2026-02-10T09:53:48.923Z [WARN] Streaming stall detected: 72.7s gap between events (stall #1)
2026-02-10T09:53:50.042Z [ERROR] Error streaming, falling back to non-streaming mode: Content block is not a input_json block
Session JSONL (final line) corruption symptom:
- File: .claude/projects/-Users-crystal--wegent-executor-workspace-271413/5a2ef95e-645f-41ea-8451-99c5506589ef.jsonl
- Previous line (84): normal `message` object with keys like `content`, `id`, `model`, `role`, `stop_reason`, `usage`
- Final line (85): `message` becomes a dict with numeric keys `"0".."8351"` (character fragments), `role` missing, `content` empty
Quick structure check (line 85):
message_type: dict
key_count: 8353
has_role: False
has_content: True
first_15_keys: ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14']
content_type: list
content_len: 0
Character-split evidence from final JSONL record:
- message["0"] = "{"
- message["1"] = "\""
- message["2"] = "c"
- message["3"] = "o"
- message["4"] = "n"
- message["5"] = "t"
- message["6"] = "e"
- message["7"] = "n"
- message["8"] = "t"
- ...
This indicates the assistant message payload was serialized into per-character indexed keys instead of a normal message object.
If needed, I can also give you a redacted version with absolute paths removed.
Steps to Reproduce
- Launch Claude Code (2.1.38) and start a fresh session.
- Use repeated browser automation via Bash (calling browser-tool) and continue for many turns, including some large tool outputs.
- Keep interacting until debug logs show streaming degradation and fallback:
Streaming stall detected ...
Error streaming, falling back to non-streaming mode: Content block is not a input_json block
- Open .claude/projects/.../<session-id>.jsonl for that session.
- Verify the final entry is corrupted: message is converted into numeric character-index keys ("0", "1", ...), role is missing, and content is empty, while the previous entry is schema-correct.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.38 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗