{"record":{"id":"a0c2048c40ad593b","repo":"BerriAI/litellm","slug":"oci-only-supports-function-tool-calls","errorCode":null,"errorMessage":"OCI only supports function tool calls","messagePattern":"OCI only supports function tool calls","errorType":"validation","errorClass":"OCIError","httpStatus":400,"severity":"error","filePath":"litellm/llms/oci/chat/generic.py","lineNumber":121,"sourceCode":"                )\n            new_content.append(OCIImageContentPart(imageUrl=OCIImageUrl(url=image_url)))\n\n    return OCIMessage(\n        role=open_ai_to_generic_oci_role_map[role],\n        content=new_content,\n        toolCalls=None,\n        toolCallId=None,\n    )\n\n\ndef adapt_messages_to_generic_oci_standard_tool_call(role: str, tool_calls: list) -> OCIMessage:\n    \"\"\"Convert an assistant tool-call message to OCI format.\"\"\"\n    tool_calls_formatted: Final = []\n    for tool_call in tool_calls:\n        if not isinstance(tool_call, dict):\n            raise OCIError(status_code=400, message=\"Each tool call must be a dictionary\")\n        if tool_call.get(\"type\") != \"function\":\n            raise OCIError(status_code=400, message=\"OCI only supports function tool calls\")\n\n        tool_call_id = tool_call.get(\"id\")\n        if not isinstance(tool_call_id, str):\n            raise OCIError(status_code=400, message=\"Tool call `id` must be a string\")\n\n        tool_function = tool_call.get(\"function\")\n        if not isinstance(tool_function, dict):\n            raise OCIError(status_code=400, message=\"Tool call `function` must be a dictionary\")\n\n        function_name = tool_function.get(\"name\")\n        if not isinstance(function_name, str):\n            raise OCIError(status_code=400, message=\"Tool call `function.name` must be a string\")\n\n        arguments = tool_call[\"function\"].get(\"arguments\", \"{}\")\n        if not isinstance(arguments, str):\n            raise OCIError(\n                status_code=400,\n                message=\"Tool call `function.arguments` must be a JSON string\",","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/oci/chat/generic.py#L103-L139","documentation":"OCI GENERIC only implements function tool calls, so each tool_call object in an assistant message must have type == \"function\". Any other type (or missing type, which compares != \"function\") raises OCIError 400 in adapt_messages_to_generic_oci_standard_tool_call. The whitelist mirrors OCI's FUNCTION-only tool-call surface.","triggerScenarios":"Assistant history containing {\"type\":\"code_interpreter\",...} or tool-call objects missing the type key, sent to an oci/generic.* model. Note that a missing `type` also triggers this (None != \"function\"), so partially-built objects fail here too.","commonSituations":"Porting agent histories from OpenAI with code_interpreter/retrieval/function variants; trimming tool_call dicts (dropping type) when compressing context; merging tool schemas from multiple providers; custom tool-call types invented by frameworks.","solutions":["Ensure every tool_call has \"type\": \"function\" alongside id and function fields","Strip non-function tool calls from history before sending to OCI (they can't be represented)","When rebuilding trimmed histories, preserve all keys or re-serialize from the original response object","Log offending tool_call objects at build time to catch dropped keys early"],"exampleFix":"# before\n{\"role\": \"assistant\", \"tool_calls\": [{\"id\": \"1\", \"function\": {\"name\": \"f\"}}]}  # type missing\n\n# after\n{\"role\": \"assistant\", \"tool_calls\": [{\"id\": \"1\", \"type\": \"function\", \"function\": {\"name\": \"f\", \"arguments\": \"{}\"}}]}","handlingStrategy":"validation","validationCode":"def normalize_tool_call_types(tool_calls: list) -> list:\n    return [tc for tc in tool_calls if isinstance(tc, dict) and tc.get(\"type\") == \"function\"]","typeGuard":"def is_function_tool_call(tc) -> bool:\n    return isinstance(tc, dict) and tc.get(\"type\") == \"function\"","tryCatchPattern":null,"preventionTips":["When trimming history, whitelist keys (id, type, function) instead of blacklisting","Strip provider-specific tool types (code_interpreter etc.) before forwarding history to OCI"],"tags":["oci","tool-calls","function-calling","request-validation"],"backgroundTag":"unsupported-tool-call-type","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}