Session permanently broken with 400 'unexpected end of data' after binary tool output (real-world case of #94055)

Status Open
Reported on v2.1.270
Maintainer reply None cached
Activity 1 comment · opened Sep 14, 2026

Summary

A long-running Claude Code session (CLI, v2.1.270/271) becomes permanently broken with repeated 400 errors:

API Error: 400 The request body is not valid JSON: unexpected end of data: line 1 column N (char N-1)

The session never recovers — every subsequent turn, including fork sub-agents, hits the same error. Restarting Claude Code and resuming the session recovers temporarily, but the error recurs as the session continues.

This is likely the same root cause as #94055 (NUL bytes in Bash tool output causing JSON body truncation). The session involved processing binary ciphertext data, and some Bash tool results likely contained NUL or non-UTF-8 bytes that poisoned the conversation history.

Relationship to #94055

This issue provides additional real-world signal on the same underlying bug:

  • Real-world trigger: Binary data processed by CLI tools (not a synthetic repro)
  • Persistence across restarts: The error recurs when resuming the session after restarting Claude Code, because the poisoned tool result is replayed from the session transcript
  • Escalating truncation positions: The column position increases over time as more content accumulates, suggesting the truncation tracks the position of the bad bytes
  • Sub-agent propagation: Fork sub-agents inherit the poisoned context and also fail
  • Not a context-size issue: Session was at ~58% context utilization when errors began

Error Details

  • Total occurrences: 30 error entries in the session transcript across 3 distinct time clusters
  • Truncation column positions (chars, sorted):
  • Cluster 1 (~19:19-19:21 UTC): 1,033,239 → 1,033,372 → 1,034,660 → 1,037,925 → 1,038,214 → 1,038,361 → 1,039,533 → 1,039,680
  • Cluster 2 (~21:37 UTC): 1,540,449
  • Cluster 3 (~22:38-23:28 UTC): 1,647,727 → 1,647,995 → 1,723,655
  • Pattern: Column positions increase between clusters (session grew between restarts), but vary slightly within a cluster (different tool call overhead per request)

Sample Request IDs

req_011Cf3sahuzbPYZF1biu3qvj
req_011Cf3sajSX3ik9VUjQGLyJB
req_011Cf3scU957xDJRoqyBWc3K
req_011Cf446NM1cYbpXGNrRdppy
req_011Cf48iDsFFUqhwHSQ4JUFW
req_011Cf4CZXLgprhoMbUwogUqA

Environment

  • Claude Code version: 2.1.270 (upgraded to 2.1.271 mid-session)
  • OS: macOS Darwin 25.6.0
  • Model: claude-opus-4-6 (1M context)
  • Session duration: 7+ hours before first error
  • Context utilization at error onset: ~58%
  • Sub-agents spawned: 30+, including forks

Expected Behavior

Claude Code should either:

  1. Sanitize tool output to remove NUL/non-UTF-8 bytes before adding to conversation history
  2. Detect the serialization failure before sending and provide a clear error with recovery options (e.g., auto-compact to drop the poisoned message)
  3. Not replay poisoned tool results from the session transcript on restart

Additional Notes

  • The session involved Bash commands that processed binary ciphertext data — standard CLI workflows that can produce binary output
  • autoCompactEnabled was set to false, so the poisoned content was never automatically compacted away
  • Even with auto-compact enabled, the issue would likely persist since the poisoned message stays in the transcript

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗