BerriAI/litellm · error · Exception
Unable to convert openai tool calls={message} to gemini tool
Error message
Unable to convert openai tool calls={message} to gemini tool calls. Received error={e} What it means
Catch-all wrapper around convert_to_gemini_tool_call: any exception raised while converting your OpenAI tool calls to Gemini format (including the 'function_call missing' errors) is re-raised as this Exception with the original message and error embedded. It signals that the assistant tool-call portion of your messages is not convertible to Vertex/Gemini's functionCall part shape.
Source
Thrown at litellm/litellm_core_utils/prompt_templates/factory.py:1360
)
if isinstance(provider_fields, dict):
thought_signature = provider_fields.get("thought_signature")
# If no signature found and model is gemini-3, use dummy signature
if not thought_signature and model and VertexGeminiConfig._is_gemini_3_or_newer(model):
thought_signature = _get_dummy_thought_signature()
if thought_signature:
part_dict_function["thoughtSignature"] = thought_signature
_parts_list.append(part_dict_function)
else: # don't silently drop params. Make it clear to user what's happening.
raise Exception(
f"function_call missing. Received tool call with 'type': 'function'. No function call in argument - {message}"
)
return _parts_list
except Exception as e:
raise Exception(f"Unable to convert openai tool calls={message} to gemini tool calls. Received error={e}")
def convert_to_gemini_tool_call_result(
message: ChatCompletionToolMessage | ChatCompletionFunctionMessage,
last_message_with_tool_calls: dict | None,
forward_function_call_id: bool = False,
) -> VertexPartType | list[VertexPartType]:
"""
OpenAI message with a tool result looks like:
{
"tool_call_id": "tool_1",
"role": "tool",
"content": "function result goes here",
},
# NOTE: Function messages have been deprecated
OpenAI message with a function call result looks like:
{View on GitHub (pinned to 6c2dcb801b)
Solutions
- Read the trailing 'Received error=' clause — it contains the specific converter failure (usually function_call missing)
- Repair the tool call entries so each has type 'function' and a function dict with a non-empty name and JSON-string arguments
- Drop the corrupted assistant tool-call turn and regenerate it if it cannot be repaired
Example fix
# before
assistant_msg = {"role": "assistant", "tool_calls": json.loads(db_row.tool_calls)} # rows may be malformed
litellm.completion(model="gemini/gemini-1.5-pro", messages=[*history, assistant_msg])
# after
assistant_msg = {"role": "assistant", "tool_calls": json.loads(db_row.tool_calls)}
assistant_msg["tool_calls"] = [
tc for tc in assistant_msg["tool_calls"]
if isinstance(tc.get("function"), dict) and tc["function"].get("name")
]
assert assistant_msg["tool_calls"], "no valid tool calls to replay"
litellm.completion(model="gemini/gemini-1.5-pro", messages=[*history, assistant_msg]) Defensive patterns
Strategy: try-catch
Validate before calling
def gemini_replayable(messages) -> bool:
for m in messages:
if m.get("role") == "assistant":
for tc in m.get("tool_calls") or []:
fn = tc.get("function") if isinstance(tc, dict) else None
if not (isinstance(fn, dict) and fn.get("name")):
return False
fc = m.get("function_call")
if fc is not None and not (isinstance(fc, dict) and fc.get("name")):
return False
return True Try / catch
try:
resp = litellm.completion(model="gemini/gemini-2.0-flash", messages=messages, tools=tools)
except Exception as e:
if "Unable to convert openai tool calls" in str(e):
messages = [m for m in messages if message_tool_calls_valid(m)] # drop/repair bad turns
resp = litellm.completion(model="gemini/gemini-2.0-flash", messages=messages, tools=tools)
else:
raise Prevention
- Sanitize stored tool-call history before replaying to Gemini
- Log the embedded 'Received error=' clause to find the exact bad entry
- Regenerate corrupted assistant turns instead of forwarding them
When it happens
Trigger: Any malformed assistant tool_calls/function_call entry (missing function.name, wrong types) sent to gemini/* or vertex_ai/* models; unexpected dict shapes after JSON (de)serialization of histories.
Common situations: Agent loops replaying stored or hand-built assistant messages to Gemini; cross-provider history migration; upstream models emitting non-standard tool call fields that got persisted.
Related errors
- function_call missing. Received tool call with 'type': 'func
- function_call missing. Received tool call with 'type': 'func
- Missing corresponding tool call for tool response message. R
- Failed to parse tool call arguments. Error: {original_error}
- image conversion failed please run `pip install Pillow`
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/0dd34a3107edd9c6.
Report an issue: GitHub.