BerriAI/litellm · error · Exception
function_call missing. Received tool call with 'type': 'func
Error message
function_call missing. Received tool call with 'type': 'function'. No function call in argument - {tool} What it means
While converting an OpenAI tool_calls list to Gemini format, a tool entry had type 'function' but its `function` payload (name/arguments) was missing or unusable, so the helper returned None. LiteLLM deliberately raises instead of silently dropping the malformed tool call. The whole message is included so you can see which entry is bad.
Source
Thrown at litellm/litellm_core_utils/prompt_templates/factory.py:1330
VertexGeminiConfig,
)
if tool_calls is not None:
for idx, tool in enumerate(tool_calls):
if "function" in tool:
gemini_function_call: VertexFunctionCall | None = _gemini_tool_call_invoke_helper(
function_call_params=tool["function"],
tool_call_id=(tool.get("id") if forward_function_call_id else None),
)
if gemini_function_call is not None:
part_dict: VertexPartType = {"function_call": gemini_function_call}
thought_signature = _get_thought_signature_from_tool(dict(tool), model=model)
if thought_signature:
part_dict["thoughtSignature"] = thought_signature
_parts_list.append(part_dict)
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 - {tool}"
)
elif function_call is not None:
gemini_function_call = _gemini_tool_call_invoke_helper(function_call_params=function_call)
if gemini_function_call is not None:
part_dict_function: Final[VertexPartType] = {"function_call": gemini_function_call}
# Extract thought signature from function_call's provider_specific_fields
thought_signature = None
provider_fields: Final = (
function_call.get("provider_specific_fields") if isinstance(function_call, dict) else {}
)
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()View on GitHub (pinned to 6c2dcb801b)
Solutions
- Inspect the offending entry in the error message and fix its 'function' dict to include a valid 'name' (and 'arguments')
- If you build tool_calls yourself, always include {"type":"function","function":{"name":..., "arguments":"{}"}}
- Sanitize stored histories: drop or repair tool_calls entries whose function/name is falsy before sending to Gemini
Example fix
# before
history.append({
"role": "assistant",
"tool_calls": [{"id": "call_1", "type": "function", "function": {}}],
})
litellm.completion(model="gemini/gemini-2.0-flash", messages=history, tools=tools)
# after
history.append({
"role": "assistant",
"tool_calls": [{"id": "call_1", "type": "function",
"function": {"name": "get_weather", "arguments": "{\"city\": \"SF\"}"}}],
}) Defensive patterns
Strategy: validation
Validate before calling
def tool_calls_are_well_formed(tool_calls) -> bool:
for tc in tool_calls or []:
fn = tc.get("function") if isinstance(tc, dict) else None
if not isinstance(fn, dict) or not fn.get("name"):
return False
return True
for m in messages:
if m.get("role") == "assistant" and not tool_calls_are_well_formed(m.get("tool_calls")):
raise ValueError(f"malformed tool_calls in assistant message: {m}") Type guard
from typing import Any
def is_valid_tool_call(tc: Any) -> bool:
return (
isinstance(tc, dict)
and tc.get("type") == "function"
and isinstance(tc.get("function"), dict)
and bool(tc["function"].get("name"))
) Prevention
- Always include function.name and arguments when constructing assistant tool_calls
- Validate persisted histories after JSON round-trips
- Never replay tool calls whose function dict is empty
When it happens
Trigger: An assistant message with tool_calls=[{"id":..., "type":"function", "function": None}] or function lacking a 'name'; tool calls reconstructed from logs/DB where the function dict was dropped; calling Vertex/Gemini models after resuming an agent conversation with corrupted tool-call history.
Common situations: Replaying persisted conversations where JSON round-trips dropped nested function objects; hand-crafted assistant tool_calls in tests; upstream provider returned a degenerate tool call that was stored verbatim.
Related errors
- Unable to convert openai tool calls={message} to gemini tool
- Missing corresponding tool call for tool response message. R
- function_call missing. Received tool call with 'type': 'func
- 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/2afb5e59e2485cd9.
Report an issue: GitHub.