BerriAI/litellm · error · OCIError
OCI only supports function tool calls
Error message
OCI only supports function tool calls
What it means
The OCI GENERIC inference API only supports function-type tool calls. During adaptation, any tool call whose 'type' field is not exactly 'function' raises OCIError(400) 'OCI only supports function tool calls'. This rejects future/alternate OpenAI tool call kinds (e.g. 'custom_function', 'code_interpreter') before the request is sent.
Source
Thrown at litellm/llms/oci/chat/generic.py:121
)
new_content.append(OCIImageContentPart(imageUrl=OCIImageUrl(url=image_url)))
return OCIMessage(
role=open_ai_to_generic_oci_role_map[role],
content=new_content,
toolCalls=None,
toolCallId=None,
)
def adapt_messages_to_generic_oci_standard_tool_call(role: str, tool_calls: list) -> OCIMessage:
"""Convert an assistant tool-call message to OCI format."""
tool_calls_formatted: Final = []
for tool_call in tool_calls:
if not isinstance(tool_call, dict):
raise OCIError(status_code=400, message="Each tool call must be a dictionary")
if tool_call.get("type") != "function":
raise OCIError(status_code=400, message="OCI only supports function tool calls")
tool_call_id = tool_call.get("id")
if not isinstance(tool_call_id, str):
raise OCIError(status_code=400, message="Tool call `id` must be a string")
tool_function = tool_call.get("function")
if not isinstance(tool_function, dict):
raise OCIError(status_code=400, message="Tool call `function` must be a dictionary")
function_name = tool_function.get("name")
if not isinstance(function_name, str):
raise OCIError(status_code=400, message="Tool call `function.name` must be a string")
arguments = tool_call["function"].get("arguments", "{}")
if not isinstance(arguments, str):
raise OCIError(
status_code=400,
message="Tool call `function.arguments` must be a JSON string",View on GitHub (pinned to 6c2dcb801b)
Solutions
- Set 'type':'function' (exact lowercase) on every tool call you send to OCI.
- Filter or rewrite non-function tool calls from history before routing the conversation to oci/ models.
- Keep alternate tool-call kinds on a provider that supports them.
Example fix
# before
{'id':'c1','type':'custom_function','function':{...}}
# after
{'id':'c1','type':'function','function':{'name':'get_weather','arguments':'{}'}} Defensive patterns
Strategy: validation
Validate before calling
for msg in messages:
for tc in msg.get('tool_calls') or []:
if tc.get('type') != 'function':
tc['type'] = 'function' # or drop/reject per your policy Type guard
def is_function_tool_call(tc: object) -> bool:
return isinstance(tc, dict) and tc.get('type') == 'function' Try / catch
try:
litellm.completion(model='oci/...', messages=msgs)
except OCIError as e:
if 'only supports function tool calls' in str(e):
msgs = [m for m in msgs if keeps_function_calls_only(m)]
raise Prevention
- Treat 'type' as case-sensitive: always lowercase 'function'.
- Route conversations containing custom tool call kinds away from OCI GENERIC models.
When it happens
Trigger: Sending an assistant history message containing tool_calls with type 'custom_function' or any non-'function' value to an oci/ GENERIC model; round-tripping responses from providers that emit other tool call types.
Common situations: Porting an agent framework that defines custom tool call types; replaying a conversation captured on another provider; typos like 'Function' (case-sensitive comparison) or 'functions'.
Related errors
- Content type `{item_type}` is not supported by OCI
- Each tool call must be a dictionary
- Tool call `id` must be a string
- Tool call `function` must be a dictionary
- Tool call `function.name` must be a string
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/a0c2048c40ad593b.
Report an issue: GitHub.