[BUG] API Error 400 - The request body is not valid JSON: str is not valid UTF-8: surrogates not allowed - mid-conversation error
Status Open
Reported on v2.1.160
Maintainer reply None cached
Activity 8 comments · opened Jun 2, 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?
Error appeared mid-conversation without sending any images and have to start new chat and its not remember anything where left from
What Should Happen?
its not shows this error middle of Claude code conversation as its break all flows of work
Error Messages/Logs
API Error: 400 The request body is not valid JSON: str is not valid UTF-8: surrogates not allowed: line 1 column 1 (char 0)
Steps to Reproduce
Start a conversation in Claude Code (VS Code)
Continue conversation for several exchanges
Error appears without any file/image uploads
It happen since last 3 days only
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Last Working Version
last version also get error
Claude Code Version
2.1.160
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
VS Code integrated terminal
Additional Information
_No response_
8 Comments
This is happening to me as well, please fix this :-)
Also happening to me. Went through extensive debugging effort with separate Claude session, analyzing files in project context and memory, concluding that it's a bug, and referring me to the issues list. That Claude suggested I mention: "project has a .claude/ directory with ~110KB of context markdown files and 25 custom agent definitions, error triggers on first prompt after Claude Code autonomously runs tools (git status + file search), and it recurs across sessions."
We are also having the same problem. When uploading regardless of what we upload. Images included.
I keep getting this issue today
Adding a distinct data pattern from a small fleet of Windows 11 machines (Claude Code desktop app, long-lived sessions): storms + re-accumulation + relaunch-cure, which may help narrow where the lone surrogate enters.
Environment/workload: very long-lived sessions (hours to all day), heavy inbound emoji-dense chat content arriving via MCP tooling (Microsoft Teams messages), frequent screenshot pastes.
Pattern observed (5 episodes across 2 machines, 2026-07-05 → 2026-07-06):
400 ... surrogates not allowed: line 1 column 1 (char 0)with no image in the failing turn, escalating to storms — 4+ consecutive turns rejected. Notably, tool-side work in the turn still executes; only the reply/API call dies.Client-side content ruled out on our side: we ASCII-hardened every log/notification surface our own tooling feeds into the session and hex-verified recent lines pure ASCII — the 400s continued regardless. Combined with
char 0(whole-body rejection) and the relaunch-flush behavior, this points at a lone surrogate persisting in client-side request assembly state (message-history windowing / truncated tool-result or notification buffers that get re-sent every turn), consistent with the surrogate-pair-splitting analysis in #72995.Episode windows if server-side correlation helps (SAST/UTC+2): 2026-07-05 06:57–10:27 (storm), 2026-07-05 18:07–18:32 (storm), 2026-07-06 ~08:30 (single), 2026-07-06 ~10:07 (second machine).
Im getting this same error while using Claude Cowork in Windowns and asking it to read PDF/Docx files
Adding a data point that points at a network middlebox buffering the SSE stream as a root cause for the no-image / mid-conversation variant of this error.
Environment: macOS, VSCode extension (native/embedded), Claude Code v2.1.201, sitting behind Netskope Secure Web Gateway with TLS inspection (SSL decryption) enabled.
What I observe when it fails:
400 ... str is not valid UTF-8: surrogates not allowed: line 1 column 1 (char 0)fires mid-response, with no image attached and nothing queued — including while Claude is still "thinking."message_deltacarryingusage, andmessage_stop) never arrive cleanly, so the assistant turn is left partial.Hypothesis: the SWG buffers and re-chunks the
text/event-streamresponse for inspection, and a chunk boundary can land in the middle of a multi-byte UTF-8 sequence (or a surrogate pair). The client reassembles a lone/unpaired surrogate into the in-flight assistant message; that surrogate is then replayed in the message history on the next request, so the API rejects the entire body →400 surrogates not allowedon every subsequent turn.The corruption is in-flight, not persisted. After a failure I byte-scanned the session
.jsonl(737 entries) and found zero lone surrogates anywhere — the stored assistant turns are clean UTF-8. Restarting VSCode / reopening the Claude tab recovers the session. That's consistent with stream-level mangling rather than a corrupted stored transcript.Differential test to confirm: toggle the SSE-buffering middlebox (Netskope SWG in my case) off → streaming resumes token-by-token and the 400 stops. Anyone hitting the no-image variant is likely behind a proxy / gateway / endpoint-AV that buffers SSE. A do-not-decrypt / bypass exception for
api.anthropic.comon the gateway also resolves it.Possible client-side hardening: decode the SSE byte stream as UTF-8 across chunk boundaries (hold an incomplete trailing multi-byte sequence until the next chunk arrives) instead of decoding per-chunk, and/or sanitize lone surrogates out of assistant content before persisting or re-sending it — so a badly-chunked stream degrades gracefully instead of bricking the conversation.
Likely the same underlying issue as the image-attach reports (e.g. #69781), where the encode/decode path produces the same lone-surrogate symptom.
Confirming this on Windows 11, VS Code extension, CLI + extension both on v2.1.205 (latest as of 2026-07-09).
Reproduction:
API Error: 400 The request body is not valid JSON: str is not valid UTF-8: surrogates not allowed: line 1 column 1 (char 0)Ruled out while investigating:
This looks distinct from the emoji/truncation-boundary surrogate fixes shipped in v2.1.172/v2.1.187 — no emoji or special characters involved, just repeated image pastes.
Likely cause found: the affected laptop has Netskope's endpoint agent installed and running (EPDLP endpoint-DLP module + STAgent SSL-interception/traffic-steering module). Netskope's DLP inspects clipboard content, and its SSL-interception agent decrypts/inspects/re-encrypts HTTPS traffic (including this app's API calls) for content scanning before forwarding it. That would explain the 400 coming from the API itself rather than a client-side crash — the request body is likely being corrupted in-transit during Netskope's inspection/re-encoding of the payload, which is more likely to surface on larger binary payloads like base64-encoded images than plain text. My other, unaffected laptop does not have this agent installed. If others hitting this are on a corporate network with a TLS-inspecting/DLP proxy (Netskope, Zscaler, etc.), that's worth checking — the fix on my end will likely be an SSL-inspection/DLP bypass exception for Anthropic's API domains rather than anything in Claude Code itself.
(Secondary, likely unrelated: the affected laptop has no admin rights so runs Claude Code's "native" self-contained binary rather than a global npm install — mentioning in case it's relevant, though the Netskope finding above seems the stronger lead.)
Also reproduces in the plain
claudeCLI, not just the VS Code extension — same error, same "every subsequent request fails" behavior. Since the CLI and the VS Code extension use different mechanisms for attaching/pasting images, this rules out anything specific to VS Code's own clipboard-paste handling and points at something shared by both entry points: either the core CLI binary's request/encoding logic, or the network path (which for me means Netskope, intercepting everyclaude.exeflow to api.anthropic.com regardless of which entry point launched it).