BerriAI/litellm · warning · ValueError
Unknown message type: {message_str}
Error message
Unknown message type: {message_str} What it means
Raised at the tail of transform_realtime_response when the parsed JSON server frame matched none of the transformation branches and produced no returned messages — the code decodes it to a string (bytes-safe) and raises ValueError('Unknown message type: ...'). It is the catch-all for Gemini frames that are valid JSON but unrecognizable to this transformer version.
Source
Thrown at litellm/llms/gemini/realtime/transformation.py:1521
standalone_usage_metadata = json_message.get("usageMetadata")
if isinstance(standalone_usage_metadata, dict):
self._pending_usage_metadata = standalone_usage_metadata
if not unhandled_known_keys:
return {
"response": returned_message,
"current_output_item_id": current_output_item_id,
"current_response_id": current_response_id,
"current_delta_chunks": current_delta_chunks,
"current_conversation_id": current_conversation_id,
"current_item_chunks": current_item_chunks,
"current_delta_type": current_delta_type,
"session_configuration_request": session_configuration_request,
}
if isinstance(message, bytes):
message_str = message.decode("utf-8", errors="replace")
else:
message_str = str(message)
raise ValueError(f"Unknown message type: {message_str}")
current_delta_chunks = self.update_current_delta_chunks(
transformed_message=returned_message,
current_delta_chunks=current_delta_chunks,
)
current_item_chunks = self.update_current_item_chunks(
transformed_message=returned_message,
current_item_chunks=current_item_chunks,
)
for msg in returned_message:
event_type = msg.get("type") if isinstance(msg, dict) else "unknown"
verbose_logger.debug("Realtime Response Transform: OpenAI event=%s", event_type)
return {
"response": returned_message,
"current_output_item_id": current_output_item_id,
"current_response_id": current_response_id,View on GitHub (pinned to 6c2dcb801b)
Solutions
- Upgrade litellm to the latest realtime transformer.
- Catch and log the raw frame (it is embedded in the message) to identify what the server sent.
- Skip unknown frames and keep the session alive; reconnect if the same frame type repeats and blocks progress.
Example fix
# before
out = config.transform_realtime_response(message=frame, ...)
# after
try:
out = config.transform_realtime_response(message=frame, ...)
except ValueError as e:
if 'Unknown message type' in str(e):
logger.info('Skipping unknown Gemini frame: %s', e)
out = {'returned_message': []}
else:
raise
Defensive patterns
Strategy: try-catch
Try / catch
try:
out = config.transform_realtime_response(message=frame, ...)
except ValueError as e:
if "Unknown message type" in str(e):
logger.info("Ignoring unrecognized Gemini frame: %s", e)
out = {"returned_message": []}
else:
raise Prevention
- Log unknown frames (message embeds the raw payload) and monitor their frequency.
- Upgrade litellm promptly after Gemini realtime API updates.
- Design session loops to tolerate skipped frames so unknown types degrade gracefully.
When it happens
Trigger: A valid-JSON Gemini frame whose top-level shape is unknown: new event types, empty frames {}, error envelopes, or frames only partially covered by the installed litellm transformer.
Common situations: Gemini rolling out new realtime event types; API version mismatch (v1alpha frames against a v1beta-targeted transformer); error/notice frames from the infrastructure rather than the model.
Related errors
- Unexpected part type: {part}
- Unknown openai event: {key}, value: {value}
- Unexpected model turn event, no 'parts' key: {model_turn}
- Unexpected delta type: {delta_type}
- Unknown openai event: {openai_event}
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/ef6ff816b2cc8575.
Report an issue: GitHub.