BerriAI/litellm · error · ValueError
Unsupported type {type(value)} for key function_call in mess
Error message
Unsupported type {type(value)} for key function_call in message {message} What it means
For the legacy OpenAI 'function_call' field, the counter expects a mapping like {"name":..., "arguments":...}. A non-mapping value (string, list, None) cannot be read with .get('arguments'), so it raises, echoing the value's type and the message.
Source
Thrown at litellm/litellm_core_utils/token_counter.py:429
Handles both the modern `tool_calls` list and the legacy OpenAI
`function_call` dict. Only the `arguments` string is counted (matching the
existing tool_calls behavior); names are accounted for elsewhere via the
tool/function definitions and `tool_choice`.
"""
if key == "tool_calls":
if not isinstance(value, list):
raise ValueError(f"Unsupported type {type(value)} for key tool_calls in message {message}")
total = 0
for tool_call in value:
if "function" not in tool_call:
raise ValueError(f"Unsupported tool call {tool_call} must contain a function key")
function_arguments = tool_call["function"].get("arguments", "")
total += count_function(str(function_arguments))
return total
if key == "function_call":
if not isinstance(value, Mapping):
raise ValueError(f"Unsupported type {type(value)} for key function_call in message {message}")
return count_function(str(value.get("arguments", "")))
raise ValueError(f"Unexpected key {key!r}; expected 'tool_calls' or 'function_call'")
def _count_messages(
params: _MessageCountParams,
messages: list[AllMessageValues],
use_default_image_token_count: bool,
default_token_count: int | None,
) -> int:
"""
Count the number of tokens in a list of messages.
Args:
params (_MessageCountParams): The parameters for counting tokens.
messages (List[AllMessageValues]): The list of messages to count tokens in.
use_default_image_token_count (bool): When True, will NOT make a GET request to the image URL and instead return the default image dimensions.
default_token_count (Optional[int]): The default number of tokens to return for a message block, if an error occurs.View on GitHub (pinned to 6c2dcb801b)
Solutions
- Store function_call as a dict: {"name": <str>, "arguments": <json-string>} (arguments stays a string per the OpenAI spec).
- Drop null/empty function_call fields from persisted assistant messages.
Example fix
# before
msg = {"role": "assistant", "function_call": "get_weather({city: 'SF'})"}
# after
msg = {"role": "assistant",
"function_call": {"name": "get_weather", "arguments": "{\"city\": \"SF\"}"}} Defensive patterns
Strategy: type-guard
Validate before calling
from collections.abc import Mapping
fc = msg.get("function_call")
if fc is not None and not isinstance(fc, Mapping):
raise ValueError("function_call must be a dict with name/arguments")
n = litellm.token_counter(model=m, messages=msgs) Type guard
from collections.abc import Mapping
def is_valid_function_call(value) -> bool:
return isinstance(value, Mapping) and isinstance(value.get("arguments", ""), str) Prevention
- Keep legacy function_call as {name, arguments-json-string}; never store it stringified.
- Drop null function_call keys when persisting assistant messages.
When it happens
Trigger: Assistant messages with function_call stored as a plain string (e.g. "get_weather(...)") instead of a dict, or function_call set to a list or null on legacy function-calling traffic passed to token_counter or cost accounting.
Common situations: Migrating old OpenAI function-calling logs into LiteLLM accounting; agent frameworks that stringify function calls for logging and reuse the object for counting; schema drift between stored and expected shapes.
Related errors
- function_call missing. Received tool call with 'type': 'func
- text and messages cannot both be set
- tools or tool_choice cannot be set if using text
- Either text or messages must be provided
- Unsupported type {type(value)} for key tool_calls in message
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/897e741d90839c85.
Report an issue: GitHub.