BerriAI/litellm · error · RuntimeError

Error parsing chunk: {e}, Received chunk: {chunk}

Error message

Error parsing chunk: {e},
Received chunk: {chunk}

What it means

After a raw line is received and handed to _handle_string_chunk (which typically strips 'data:' prefixes and json.loads the payload), a ValueError from parsing — most commonly invalid JSON — is re-raised as RuntimeError together with the offending chunk. This catches malformed SSE payloads rather than transport errors.

Source

Thrown at litellm/llms/base_llm/base_model_iterator.py:163

                str_line = chunk
                if isinstance(chunk, bytes):  # Handle binary data
                    str_line = chunk.decode("utf-8")  # Convert bytes to string
                    index = str_line.find("data:")
                    if index != -1:
                        str_line = str_line[index:]

                # Skip empty lines (common in SSE streams between events).
                # Only apply to str chunks — non-string objects (e.g. Pydantic
                # BaseModel events from the Responses API) must pass through.
                if isinstance(str_line, str) and (not str_line or not str_line.strip()):
                    continue

                # chunk is a str at this point
                return self._handle_string_chunk(str_line=str_line)
            except StopIteration:
                raise StopIteration
            except ValueError as e:
                raise RuntimeError(f"Error parsing chunk: {e},\nReceived chunk: {chunk}")

    # Async iterator
    def __aiter__(self):
        self.async_response_iterator = self.streaming_response.__aiter__()
        return self

    async def __anext__(self):
        while True:
            try:
                chunk = await self.async_response_iterator.__anext__()

            except StopAsyncIteration:
                raise StopAsyncIteration
            except ValueError as e:
                raise RuntimeError(f"Error receiving chunk from stream: {e}")

            try:
                str_line = chunk

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Inspect the 'Received chunk:' portion — if it is HTML or partial JSON, the stream was corrupted upstream (proxy/timeout)
  2. Increase proxy/gateway read timeouts (e.g. nginx proxy_read_timeout) for long generations
  3. Retry with streaming; if reproducible, fall back to stream=False for that model
  4. Report to the provider if the chunk shows valid-looking but malformed JSON from their side
Defensive patterns

Strategy: try-catch

Try / catch

try:
    for chunk in litellm.completion(model=m, messages=msgs, stream=True):
        handle(chunk)
except RuntimeError as e:
    if 'Error parsing chunk' in str(e):
        if '<html' in str(e).lower():
            raise GatewayError('proxy injected HTML into SSE stream') from e
        # else: retry or fall back to stream=False

Prevention

When it happens

Trigger: A streaming completion where a 'data:' line contains invalid JSON (truncated by a proxy timeout, HTML error page injected mid-stream, or a provider bug). Also when a custom iterator returns non-conforming strings.

Common situations: Corporate proxies or load balancers truncating long SSE responses; provider returning a 200 then error HTML; overloaded gateways splitting chunks at non-token boundaries; custom provider adapters emitting non-JSON data lines.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/02c6d5cbd2ea956d. Report an issue: GitHub.