[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

  1. Launch Claude Code (2.1.38) and start a fresh session.
  2. Use repeated browser automation via Bash (calling browser-tool) and continue for many turns, including some large tool outputs.
  3. 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

  1. Open .claude/projects/.../<session-id>.jsonl for that session.
  2. 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_

View original on GitHub ↗

This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗