{"record":{"id":"8127354fae33233a","repo":"BerriAI/litellm","slug":"advisor-tool-must-have-a-valid-model","errorCode":null,"errorMessage":"Advisor tool must have a valid model","messagePattern":"Advisor tool must have a valid model","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/anthropic/chat/transformation.py","lineNumber":759,"sourceCode":"        elif tool[\"type\"] == \"tool_search_tool_bm25_20251119\":\n            # Tool search tool using BM25\n            from litellm.types.llms.anthropic import AnthropicToolSearchToolBM25\n\n            tool_name_obj = tool.get(\"name\", \"tool_search_tool_bm25\")\n            if not isinstance(tool_name_obj, str):\n                raise ValueError(\"Tool search tool must have a valid name\")\n            tool_name = tool_name_obj\n            returned_tool = AnthropicToolSearchToolBM25(\n                type=\"tool_search_tool_bm25_20251119\",\n                name=tool_name,\n            )\n        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)","sourceCodeStart":741,"sourceCodeEnd":777,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/anthropic/chat/transformation.py#L741-L777","documentation":"For the Anthropic advisor tool (ANTHROPIC_ADVISOR_TOOL_TYPE), LiteLLM requires tool['model'] to be a string naming the advisor model; it builds AnthropicAdvisorTool(name='advisor', model=...). A missing or non-string 'model' raises this ValueError client-side.","triggerScenarios":"Passing {'type': <advisor type>, 'max_uses': 2} without 'model', or with 'model': None / a dict. The advisor tool always needs the backing model specified.","commonSituations":"Enabling the advisor feature from release notes without copying the full required fields; environment-driven configs where the model variable was empty and serialized as None.","solutions":["Add 'model': '<model-id>' (a string, e.g. the advisor model Anthropic documents) to the advisor tool dict.","Verify optional extras (max_uses, caching) are separate keys; only 'model' is mandatory.","Default empty strings from config to a concrete model id before building the tool."],"exampleFix":"# before\n{\"type\": \"advisor_20251119\", \"max_uses\": 2}\n\n# after\n{\"type\": \"advisor_20251119\", \"model\": \"claude-sonnet-4-5\", \"max_uses\": 2}","handlingStrategy":"validation","validationCode":"if tool.get(\"type\") == \"advisor_20251119\":\n    m = tool.get(\"model\")\n    if not isinstance(m, str) or not m:\n        raise ValueError(\"advisor tool requires a non-empty string 'model'\")","typeGuard":"def advisor_tool_valid(tool) -> bool:\n    return isinstance(tool.get(\"model\"), str) and len(tool[\"model\"]) > 0","tryCatchPattern":null,"preventionTips":["Default advisor model from config with a concrete fallback string.","Reject empty-string model values early — they pass 'is not None' but fail isinstance checks downstream in spirit."],"tags":["anthropic","tools","advisor","validation"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}