BerriAI/litellm · error · ValueError
Error transforming content delta events: {e}, got message: {
Error message
Error transforming content delta events: {e}, got message: {message} What it means
Raised in transform_content_delta_event when any exception occurs while walking message['modelTurn']['parts'] and accumulating 'text' / 'inlineData.data' values — for example a part is not a dict, inlineData is not a dict, or keys are missing in unexpected ways. The original exception is wrapped in a ValueError together with the raw message for diagnosis.
Source
Thrown at litellm/llms/gemini/realtime/transformation.py:737
return response_items
def transform_content_delta_events(
self,
message: BidiGenerateContentServerContent,
output_item_id: str,
response_id: str,
delta_type: ALL_DELTA_TYPES,
) -> OpenAIRealtimeResponseDelta:
delta = ""
try:
if "modelTurn" in message and "parts" in message["modelTurn"]:
for part in message["modelTurn"]["parts"]:
if "text" in part:
delta += part["text"]
elif "inlineData" in part:
delta += part["inlineData"].get("data", "")
except Exception as e:
raise ValueError(f"Error transforming content delta events: {e}, got message: {message}")
return OpenAIRealtimeResponseDelta(
type=("response.output_text.delta" if delta_type == "text" else "response.output_audio.delta"),
content_index=0,
event_id=f"event_{uuid.uuid4()}",
item_id=output_item_id,
output_index=0,
response_id=response_id,
delta=delta,
)
def transform_content_done_event(
self,
delta_chunks: list[OpenAIRealtimeResponseDelta] | None,
current_output_item_id: str | None,
current_response_id: str | None,
delta_type: ALL_DELTA_TYPES,
) -> OpenAIRealtimeResponseTextDone | OpenAIRealtimeResponseAudioDone:View on GitHub (pinned to 6c2dcb801b)
Solutions
- Upgrade litellm to the latest release (streaming schema fixes land frequently).
- Log e.args to capture the wrapped message and confirm the frame shape; report it if it's a new server format.
- Wrap per-frame transformation in try/except to drop corrupt frames instead of ending the stream.
Example fix
# before
delta = config.transform_content_delta_event(message, item_id, resp_id, delta_type)
# after
try:
delta = config.transform_content_delta_event(message, item_id, resp_id, delta_type)
except ValueError as e:
logger.warning('Dropping malformed delta frame: %s', e)
delta = None
Defensive patterns
Strategy: try-catch
Validate before calling
def is_wellformed_delta_frame(message: dict) -> bool:
try:
parts = message["modelTurn"]["parts"]
except (KeyError, TypeError):
return False
return all(
isinstance(p, dict) and ("text" in p or isinstance(p.get("inlineData"), dict))
for p in parts
) Type guard
def is_wellformed_delta_frame(message: object) -> bool:
if not isinstance(message, dict):
return False
turn = message.get("modelTurn")
if not isinstance(turn, dict) or not isinstance(turn.get("parts"), list):
return False
return all(
isinstance(p, dict) and ("text" in p or isinstance(p.get("inlineData"), dict))
for p in turn["parts"]
) Try / catch
try:
delta = config.transform_content_delta_event(message, item_id, resp_id, delta_type)
except ValueError as e:
if "Error transforming content delta" in str(e):
logger.warning("Dropping malformed delta frame: %s", e)
delta = None
else:
raise Prevention
- Treat single malformed delta frames as droppable; never let them end the stream.
- Capture and report the raw frame embedded in the error to detect schema drift.
- Keep litellm updated alongside Gemini realtime API changes.
When it happens
Trigger: A serverContent delta frame whose modelTurn.parts entries have an unexpected shape (part is a string, inlineData missing 'data' as a dict, None entries), causing AttributeError/TypeError inside the accumulation loop.
Common situations: Gemini API schema drift on the streaming path; partially decoded frames from a flaky proxy; litellm version older than the current Gemini realtime wire format.
Related errors
- Unexpected part type: {part}
- Unexpected model turn event, no 'parts' key: {model_turn}
- The response was blocked by VertexAI. {chunk}
- Error parsing chunk: {e}, Received chunk: {chunk}
- error_message or raw_response.text
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/e824d0971267b891.
Report an issue: GitHub.