{"record":{"id":"2837748520485553","repo":"BerriAI/litellm","slug":"chat-provider-empty-parsed-chunk","errorCode":null,"errorMessage":"Chat provider: Empty parsed_chunk","messagePattern":"Chat provider: Empty parsed_chunk","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/completion_extras/litellm_responses_transformation/transformation.py","lineNumber":1221,"sourceCode":"            parsed_chunk: Dict containing the Responses API event chunk\n            tool_call_index_map: Per-stream output_index -> sequential tool_call index map\n\n        Returns:\n            ModelResponseStream: OpenAI-formatted streaming chunk\n\n        Raises:\n            ValueError: If chunk is invalid or missing required fields\n        \"\"\"\n        from litellm.types.llms.openai import ChatCompletionToolCallFunctionChunk\n        from litellm.types.utils import (\n            ChatCompletionToolCallChunk,\n            Delta,\n            ModelResponseStream,\n            StreamingChoices,\n        )\n\n        if not parsed_chunk:\n            raise ValueError(\"Chat provider: Empty parsed_chunk\")\n\n        if isinstance(parsed_chunk, BaseModel):\n            parsed_chunk = parsed_chunk.model_dump()\n        if not isinstance(parsed_chunk, dict):\n            raise ValueError(f\"Chat provider: Invalid chunk type {type(parsed_chunk)}\")\n\n        # Handle different event types from responses API\n        event_type = parsed_chunk.get(\"type\")\n        if isinstance(event_type, ResponsesAPIStreamEvents):\n            event_type = event_type.value\n\n        if parsed_chunk.get(\"object\") == \"chat.completion.chunk\" or (\n            event_type is None and isinstance(parsed_chunk.get(\"choices\"), list) and parsed_chunk.get(\"choices\")\n        ):\n            return ModelResponseStream(**parsed_chunk)\n\n        verbose_logger.debug(\"Chat provider: Processing event type: %s\", event_type)\n","sourceCodeStart":1203,"sourceCodeEnd":1239,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/completion_extras/litellm_responses_transformation/transformation.py#L1203-L1239","documentation":"The chunk transformer raises when handed an empty/falsy parsed_chunk (None, empty dict). This method converts Responses API stream events into chat.completion.chunk objects for callers bridging a Responses stream into the chat-completions streaming shape; an empty event means the upstream event deserialization or a custom generator produced nothing.","triggerScenarios":"A generator feeding the transformer yields None or {} — e.g. a custom SSE parser that emits empty placeholders on keep-alive/comment events, or middleware filtering events down to nothing.","commonSituations":"Custom streaming adapters between provider SSE and the bridge; proxies forwarding comment-only SSE lines as empty dicts; test fixtures with empty event dicts.","solutions":["Skip empty events before transformation: `if not chunk: continue` in your generator","If parsing SSE yourself, ignore comment lines (`:` prefix) and non-event frames instead of yielding empty dicts","Log the raw event stream to find which frame produced the empty chunk"],"exampleFix":"# before\nfor chunk in sse_parser(raw_stream):\n    transformed = transformer.chunk_parser(chunk)  # chunk may be {}\n\n# after\nfor chunk in sse_parser(raw_stream):\n    if not chunk:\n        continue\n    transformed = transformer.chunk_parser(chunk)","handlingStrategy":"validation","validationCode":"def chunk_nonempty(chunk) -> bool:\n    return bool(chunk)","typeGuard":null,"tryCatchPattern":"for raw in event_source:\n    if not raw:\n        continue  # skip keep-alives/empties\n    out = transformer.chunk_parser(raw, ...)","preventionTips":["Skip falsy events in your stream generator","Ignore SSE comment lines and non-data frames when parsing manually"],"tags":["streaming","chunk-transformer","validation"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}