Response Parsing & Encoding Errors
JSON parse, UTF-8 encoding, SSE frame errors — the fix for each.
16 documented errorsErrors in this category
JSON.parse throws on unexpected token; usually markdown fences or preamble around JSON.
Response cut off mid-JSON; check max_tokens or read timeout.
Response contains raw control characters (0x00-0x1F) that aren't escaped.
Model output includes trailing commas; use JSON5 or repair before parsing.
Response includes // or /* */ comments; standard JSON doesn't allow them.
Response bytes don't decode as valid UTF-8; usually charset mismatch.
String comparison fails because same visual character has multiple unicode forms.
Emoji or wide characters split across stream chunks, corrupting the character.
Response includes UTF-8 BOM (byte order mark) that some parsers reject.
Server-Sent Events frame split incorrectly; missing double-newline separator.
SSE data field content isn't the expected JSON shape.
Expected event type field is missing from stream frame.
SSE retry directive has non-numeric value; parser rejects it.
Related pillar guides
Related blog posts
Frequently asked questions
Why does JSON.parse fail on responses I can see are valid JSON?
Almost always: hidden characters. Markdown fences (```json ... ```), BOM at the start (0xEF 0xBB 0xBF), invisible control characters, or trailing whitespace with a preamble. Strip these before parsing. See G8 Chapter 6 for the repair patterns.
What's the difference between UTF-8 and unicode normalization?
UTF-8 is how characters encode as bytes. Unicode normalization is how the same visual character is represented (é can be one codepoint or 'e' + combining acute accent). Same-looking strings can compare unequal. Fix: normalize both sides with normalize('NFC') before comparing.
Why do emoji sometimes come through corrupted in streaming responses?
Emoji are often 4-byte UTF-8 sequences. When they land on chunk boundaries during streaming, the naive concat can split the sequence. Fix: use TextDecoder with stream: true option (JavaScript) or io.TextIOWrapper with careful buffering (Python).
How do I debug SSE parsing errors?
Log raw bytes as they arrive (before any parsing). Look for missing \n\n separators between events, malformed 'data:' prefixes, or partial frames at connection end. Common cause: proxy stripping or reformatting SSE stream.
Should I decompress responses in my code or let the HTTP client handle it?
Let the HTTP client handle it. Node's http, Python's requests, and browser fetch all handle gzip/brotli transparently by default. Only decompress manually if you're building a low-level client or if the client's default is disabled.
What causes Content-Length mismatches?
Common causes: proxy modified the body (added logging preamble, stripped headers), transfer-encoding switched from length-prefixed to chunked and back, or connection dropped before full body arrived. The last is the most common — treat as a retry-worthy transient failure.
Are parsing errors from the provider or from my code?
Both are possible. Provider issues: content-encoding mismatch, missing headers, malformed SSE frames. Client issues: wrong charset assumption, encoding mismatch, race conditions in chunk assembly. Log raw bytes to isolate.