{"record":{"id":"5bdcca8f7b78b38c","repo":"BerriAI/litellm","slug":"unsupported-tool-type-tool-type","errorCode":null,"errorMessage":"Unsupported tool type: {tool['type']}","messagePattern":"Unsupported tool type: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/anthropic/chat/transformation.py","lineNumber":771,"sourceCode":"        elif tool[\"type\"] == ANTHROPIC_ADVISOR_TOOL_TYPE:\n            from litellm.types.llms.anthropic import AnthropicAdvisorTool\n\n            _tool_dict: Final = cast(dict, tool)\n            advisor_model: Final = _tool_dict.get(\"model\")\n            if not isinstance(advisor_model, str):\n                raise ValueError(\"Advisor tool must have a valid model\")\n            _advisor_tool: Final = AnthropicAdvisorTool(\n                type=ANTHROPIC_ADVISOR_TOOL_TYPE,\n                name=\"advisor\",\n                model=advisor_model,\n            )\n            if _tool_dict.get(\"max_uses\") is not None:\n                _advisor_tool[\"max_uses\"] = _tool_dict[\"max_uses\"]\n            if _tool_dict.get(\"caching\") is not None:\n                _advisor_tool[\"caching\"] = _tool_dict[\"caching\"]\n            returned_tool = _advisor_tool\n        if returned_tool is None and mcp_server is None:\n            raise ValueError(f\"Unsupported tool type: {tool['type']}\")\n\n        ## check if cache_control is set in the tool\n        _cache_control: Final = tool.get(\"cache_control\", None)\n        _cache_control_function: Final = tool.get(\"function\", {}).get(\"cache_control\", None)\n        if returned_tool is not None:\n            # Only set cache_control on tools that support it (not tool search tools)\n            tool_type = returned_tool.get(\"type\", \"\")\n            if tool_type not in (\n                \"tool_search_tool_regex_20251119\",\n                \"tool_search_tool_bm25_20251119\",\n            ):\n                if _cache_control is not None:\n                    returned_tool[\"cache_control\"] = _cache_control\n                elif _cache_control_function is not None and isinstance(_cache_control_function, dict):\n                    returned_tool[\"cache_control\"] = ChatCompletionCachedContent(**_cache_control_function)\n\n        ## check if defer_loading is set in the tool\n        _defer_loading: Final = tool.get(\"defer_loading\", None)","sourceCodeStart":753,"sourceCodeEnd":789,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/anthropic/chat/transformation.py#L753-L789","documentation":"The tool translation loop matched no known branch: the tool's 'type' is not 'custom'/'function', not a computer_ type, not in ANTHROPIC_HOSTED_TOOLS, not url/mcp/tool_search_*/advisor, so returned_tool and mcp_server are both None and LiteLLM rejects the tool client-side with 'Unsupported tool type: {type}'.","triggerScenarios":"Passing a tool with a typo'd or version-mismatched type string (e.g. 'computer_2024102' or a newer Anthropic type than this LiteLLM version knows), or a provider-specific type from another vendor (e.g. Google function declarations) in an anthropic/ call.","commonSituations":"LiteLLM version lag after Anthropic ships new tool types (new computer/web_search versions are dated strings); typos in hand-written type fields; reusing tool lists across providers without filtering.","solutions":["Check the exact type string against Anthropic's current docs (dated suffixes must match exactly, e.g. computer_20250124).","Upgrade LiteLLM to a version supporting the new tool type.","If the tool is a plain function tool, use type 'function' with a 'function' payload.","Filter per-provider tool lists so foreign tool types never reach the Anthropic transformation."],"exampleFix":"# before\ntools = [{\"type\": \"computer_2024102\", ...}]  # typo'd date\n\n# after\ntools = [{\"type\": \"computer_20250124\", \"function\": {\"name\": \"computer\", \"parameters\": {...}}}]","handlingStrategy":"validation","validationCode":"SUPPORTED_PREFIXES = (\"computer_\",)  # plus hosted types from litellm constants\nfrom litellm.constants import ANTHROPIC_HOSTED_TOOLS  # if available\n\ndef validate_tool_types(tools, allowed):\n    for t in tools:\n        typ = t.get(\"type\", \"\")\n        known = typ in (\"function\", \"custom\", \"url\", \"mcp\",\n                        \"tool_search_tool_regex_20251119\",\n                        \"tool_search_tool_bm25_20251119\") \\\n                or any(typ.startswith(p) for p in allowed)\n        if not known:\n            raise ValueError(f\"unsupported tool type {typ!r} for anthropic\")\n    return tools","typeGuard":"def tool_type_supported(tool) -> bool:\n    typ = tool.get(\"type\", \"\")\n    return (\n        typ in (\"function\", \"custom\", \"url\", \"mcp\",\n                \"tool_search_tool_regex_20251119\", \"tool_search_tool_bm25_20251119\")\n        or typ.startswith(\"computer_\")\n    )","tryCatchPattern":null,"preventionTips":["Copy dated tool type strings verbatim from Anthropic docs.","Upgrade LiteLLM promptly after Anthropic ships new tool versions.","Filter cross-provider tool lists per provider before each call."],"tags":["anthropic","tools","unsupported-type","validation"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}