BerriAI/litellm · error · ValueError
tool call not supported: {tool_call}
Error message
tool call not supported: {tool_call} What it means
Raised while transforming assistant tool_calls into Responses API input items: a tool call whose 'function' field is neither the standard OpenAI shape (with name/arguments) nor a dict-based custom tool call. The bridge only knows how to convert function tool calls and custom tool calls; anything else (e.g. provider-specific tool call formats) is rejected.
Source
Thrown at litellm/completion_extras/litellm_responses_transformation/transformation.py:346
"type": "function_call",
"call_id": tool_call["id"],
}
if "name" in function:
input_tool_call["name"] = function["name"]
if "arguments" in function:
input_tool_call["arguments"] = function["arguments"]
input_items.append(input_tool_call)
elif isinstance(custom, dict):
input_items.append(
ResponseCustomToolCallParam(
type="custom_tool_call",
call_id=tool_call["id"],
name=custom.get("name", ""),
input=custom.get("input", ""),
)
)
else:
raise ValueError(f"tool call not supported: {tool_call}")
elif content is not None:
if role == "assistant":
for r_item in _get_reasoning_items(msg):
input_items.append(_reasoning_item_to_response_input(r_item))
input_items.append(
{
"type": "message",
"role": role,
"content": self._convert_content_to_responses_format(content, cast(str, role)),
}
)
return input_items, instructions
def _map_optional_params_to_responses_api_request(
self,
optional_params: dict,
responses_api_request: "ResponsesAPIOptionalRequestParams",View on GitHub (pinned to 6c2dcb801b)
Solutions
- Normalize prior assistant tool_calls to the OpenAI shape before replaying: each entry needs id, type='function', function={'name': str, 'arguments': str}
- If the tool call was a custom/freeform tool, ensure the 'function' field is a dict with 'name' and 'input'
- Re-run the original tool-calling turn through the same provider so the replayed format matches
- Bypass the responses bridge for that call if you must preserve a foreign tool call format
Example fix
# before
messages = [
{"role": "assistant", "tool_calls": [
{"id": "t1", "type": "tool_use", "input": {"city": "SF"}} # non-OpenAI shape
]},
]
# after
import json
messages = [
{"role": "assistant", "tool_calls": [
{"id": "t1", "type": "function",
"function": {"name": "get_weather", "arguments": json.dumps({"city": "SF"})}}
]},
] Defensive patterns
Strategy: validation
Validate before calling
def tool_calls_bridge_safe(tool_calls: list) -> bool:
for tc in tool_calls:
fn = tc.get("function") if isinstance(tc, dict) else None
if not (isinstance(fn, dict) and "arguments" in fn):
return False
return True Type guard
def is_openai_tool_call(tc) -> bool:
return (
isinstance(tc, dict)
and isinstance(tc.get("function"), dict)
and isinstance(tc["function"].get("arguments"), str)
) Try / catch
try:
resp = litellm.completion(**bridge_kwargs)
except ValueError as e:
if "tool call not supported" in str(e):
# drop history tool_calls and retry with a text summary of the tool result
bridge_kwargs["messages"] = sanitize_tool_calls(bridge_kwargs["messages"])
resp = litellm.completion(**bridge_kwargs)
else:
raise Prevention
- Normalize tool calls to OpenAI format whenever you cross providers
- Serialize arguments as a JSON string in function.arguments
- Keep one shared converter for replaying tool results in agent loops
When it happens
Trigger: Sending back an assistant message whose tool_calls entries come from a non-OpenAI provider (e.g. Anthropic-style tool_use blocks put directly into tool_calls), or a tool_call dict missing/typing 'function' as a non-dict, while the request is routed through the chat→responses bridge.
Common situations: Multi-turn agent loops that replay tool calls captured from a different provider; hand-crafted assistant tool_call dicts; converting between provider SDK formats without normalization.
Related errors
- Unexpected responses stream payload
- Stream ended without a completed response
- Stream completed response is invalid
- Unexpected response type: {type(raw_response)}
- {model} unable to complete request: {raw_response.incomplete
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/4ba39c75f859f626.
Report an issue: GitHub.