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 - {message}

What it means

Same converter, different branch: here the assistant message used the legacy top-level `function_call` field (not tool_calls), and that function_call payload had no usable name/arguments, so the helper returned None and LiteLLM raises rather than dropping it. The full message is embedded in the error for diagnosis.

Source

Thrown at litellm/litellm_core_utils/prompt_templates/factory.py:1355

                # 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()

                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",

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Fix the function_call payload to {"name": <str>, "arguments": <json str>}
  2. Prefer the modern tool_calls format and migrate legacy histories once at load time
  3. Validate/sanitize persisted histories before replaying them against Gemini

Example fix

# before
history.append({"role": "assistant", "function_call": {"arguments": "{\"x\": 1}"}})

# after
history.append({"role": "assistant", "function_call": {"name": "get_weather", "arguments": "{\"x\": 1}"}})
Defensive patterns

Strategy: validation

Validate before calling

def function_call_is_well_formed(fc) -> bool:
    return isinstance(fc, dict) and bool(fc.get("name")) and isinstance(fc.get("arguments"), str)

for m in messages:
    fc = m.get("function_call")
    if fc is not None and not function_call_is_well_formed(fc):
        raise ValueError(f"malformed function_call in message: {m}")

Type guard

from typing import Any

def is_valid_function_call(fc: Any) -> bool:
    return isinstance(fc, dict) and bool(fc.get("name"))

Prevention

When it happens

Trigger: messages=[{"role":"assistant", "function_call": {}}] or function_call with a falsy name sent to a Gemini/Vertex model; migrating legacy OpenAI function-calling histories where the function_call object lost its 'name'.

Common situations: Old logs in the pre-tool_calls 'function_call' format; merging histories from systems that stored None names; continuing conversations captured from very old OpenAI SDK versions.

Related errors


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