BerriAI/litellm · error · ValueError

Unexpected part type: {part}

Error message

Unexpected part type: {part}

What it means

Raised in map_model_turn_event when a Gemini realtime serverContent modelTurn part contains neither a 'text' key nor an 'inlineData' key. The transformer only knows how to map text and inline-audio parts to OpenAI realtime events, so any other part shape (e.g. functionCall, videoMetadata, or a new API part type) is rejected with ValueError echoing the offending part.

Source

Thrown at litellm/llms/gemini/realtime/transformation.py:164

        Map the model turn event to the OpenAI realtime events.

        Returns either:
        - response.text.delta - model_turn: {"parts": [{"text": "..."}]}
        - response.audio.delta - model_turn: {"parts": [{"inlineData": {"mimeType": "audio/pcm", "data": "..."}}]}

        Assumes parts is a single element list.
        """
        if "parts" in model_turn:
            parts: Final = model_turn["parts"]
            if len(parts) != 1:
                verbose_logger.warning("Realtime: Expected 1 part, got %s for Gemini model turn event.", len(parts))
            part: Final = parts[0]
            if "text" in part:
                return OpenAIRealtimeEventTypes.RESPONSE_TEXT_DELTA
            elif "inlineData" in part:
                return OpenAIRealtimeEventTypes.RESPONSE_AUDIO_DELTA
            else:
                raise ValueError(f"Unexpected part type: {part}")
        raise ValueError(f"Unexpected model turn event, no 'parts' key: {model_turn}")

    def map_generation_complete_event(self, delta_type: ALL_DELTA_TYPES | None) -> OpenAIRealtimeEventTypes:
        if delta_type == "text":
            return OpenAIRealtimeEventTypes.RESPONSE_TEXT_DONE
        elif delta_type == "audio":
            return OpenAIRealtimeEventTypes.RESPONSE_AUDIO_DONE
        else:
            raise ValueError(f"Unexpected delta type: {delta_type}")

    def get_audio_mime_type(self, input_audio_format: str = "pcm16"):
        mime_types: Final = {
            "pcm16": "audio/pcm;rate=24000",
            "g711_ulaw": "audio/pcmu",
            "g711_alaw": "audio/pcma",
        }

        return mime_types.get(input_audio_format, "application/octet-stream")

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Upgrade litellm to the latest version — new Gemini part types get mapping support over time.
  2. Restrict the realtime session config (modalities/tools) so the model only emits text/audio parts.
  3. If persisting, catch the ValueError per-frame so one bad part doesn't kill the whole session.

Example fix

# before
event = config.map_model_turn_event(model_turn)

# after
try:
    event = config.map_model_turn_event(model_turn)
except ValueError:
    logger.warning('Skipping unsupported Gemini modelTurn part: %r', model_turn)
    return None  # drop the frame, keep the session alive
Defensive patterns

Strategy: try-catch

Validate before calling

def is_supported_model_turn(turn: dict) -> bool:
    parts = turn.get("parts") if isinstance(turn, dict) else None
    return bool(parts) and all(
        isinstance(p, dict) and ("text" in p or "inlineData" in p) for p in parts
    )

Type guard

def is_supported_model_turn(turn: dict) -> bool:
    if not isinstance(turn, dict) or "parts" not in turn:
        return False
    return all(
        isinstance(p, dict) and ("text" in p or "inlineData" in p)
        for p in turn["parts"]
    )

Try / catch

try:
    event = config.map_model_turn_event(model_turn)
except ValueError as e:
    if "Unexpected part type" in str(e):
        logger.warning("Skipping unsupported part: %s", e)
        continue
    raise

Prevention

When it happens

Trigger: Gemini realtime server sends a modelTurn part of a new type (function call part, tool output, future part kinds) that this litellm version's mapping does not cover; typically after Google ships new realtime capabilities.

Common situations: Upgrading the Gemini model version mid-session; litellm version lagging behind the Gemini realtime API; enabling tools/modalities the transformer doesn't handle.

Related errors


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