BerriAI/litellm · error · ValueError

Chat provider: Empty parsed_chunk

Error message

Chat provider: Empty parsed_chunk

What it means

translate_responses_chunk_to_openai_stream requires a truthy parsed_chunk: passing None, an empty dict, or another falsy value is rejected before any event handling. The translator runs inside litellm's streaming bridge, so end users see it when the provider's SSE stream contains events that decode to nothing (blank data lines, empty JSON objects) and reach the translator unfiltered, or when the API is called directly with a falsy chunk.

Solutions

  1. Skip falsy chunks before translating: 'if not chunk: continue' in any custom loop
  2. Upgrade litellm — empty-event filtering in the responses stream iterator has been tightened over releases
  3. Inspect the raw SSE frames (verbose logging) to find which event decodes to empty and report/fix the gateway
  4. Ensure json.loads results are checked for None/{} in custom parsing code

Example fix

// before
for raw in sse_lines:
    chunk = json.loads(raw) if raw.startswith("data:") else None
    out = translate_responses_chunk_to_openai_stream(chunk)  # ValueError: Chat provider: Empty parsed_chunk

// after
for raw in sse_lines:
    if not raw.startswith("data:"):
        continue
    chunk = json.loads(raw[5:])
    if not chunk:
        continue
    out = translate_responses_chunk_to_openai_stream(chunk)
Defensive patterns

Strategy: validation

Validate before calling

def chunk_is_translatable(chunk) -> bool:
    return bool(chunk)

Type guard

def is_nonempty_chunk(chunk) -> bool:
    return bool(chunk) and (isinstance(chunk, dict) or hasattr(chunk, "model_dump"))

Try / catch

try:
    out = translate_responses_chunk_to_openai_stream(chunk)
except ValueError as e:
    if "Empty parsed_chunk" in str(e):
        continue  # skip empty event, keep consuming the stream
    raise

Prevention

When it happens

Trigger: A provider or gateway emitting empty SSE 'data:' lines or '{}' events that get parsed and forwarded; keep-alive/comment frames mis-parsed as chunks; custom code calling the translator with a chunk variable that is None after a failed parse; double-processing a stream where exhaustion yields None.

Common situations: Non-OpenAI-compatible gateways in front of a Responses API; brittle custom SSE parsing; streaming tests feeding fabricated chunk sequences; older litellm versions lacking empty-event filtering.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/2837748520485553. Report an issue: GitHub.

Appendix: source

Thrown at litellm/completion_extras/litellm_responses_transformation/transformation.py:1223

            parsed_chunk: Dict containing the Responses API event chunk
            tool_call_index_map: Per-stream output_index -> sequential tool_call index map

        Returns:
            ModelResponseStream: OpenAI-formatted streaming chunk

        Raises:
            ValueError: If chunk is invalid or missing required fields
        """
        from litellm.types.llms.openai import ChatCompletionToolCallFunctionChunk
        from litellm.types.utils import (
            ChatCompletionToolCallChunk,
            Delta,
            ModelResponseStream,
            StreamingChoices,
        )

        if not parsed_chunk:
            raise ValueError("Chat provider: Empty parsed_chunk")

        if isinstance(parsed_chunk, BaseModel):
            parsed_chunk = parsed_chunk.model_dump()
        if not isinstance(parsed_chunk, dict):
            raise ValueError(f"Chat provider: Invalid chunk type {type(parsed_chunk)}")

        # Handle different event types from responses API
        event_type = parsed_chunk.get("type")
        if isinstance(event_type, ResponsesAPIStreamEvents):
            event_type = event_type.value

        if parsed_chunk.get("object") == "chat.completion.chunk" or (
            event_type is None and isinstance(parsed_chunk.get("choices"), list) and parsed_chunk.get("choices")
        ):
            return ModelResponseStream(**parsed_chunk)

        verbose_logger.debug("Chat provider: Processing event type: %s", event_type)

View on GitHub (pinned to 77b7c6c40c)