{"record":{"id":"a2926688dfba5096","repo":"microsoft/autogen","slug":"unsupported-tool-type-type-tool-a29266","errorCode":null,"errorMessage":"Unsupported tool type: {type(tool)}","messagePattern":"Unsupported tool type: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-ext/src/autogen_ext/agents/openai/_openai_agent.py","lineNumber":433,"sourceCode":"        self._instructions: str = instructions\n        self._temperature: Optional[float] = temperature\n        self._max_output_tokens: Optional[int] = max_output_tokens\n        self._json_mode: bool = json_mode\n        self._store: bool = store\n        self._truncation: str = truncation\n        self._last_response_id: Optional[str] = None\n        self._message_history: List[Dict[str, Any]] = []\n        self._tools: List[Dict[str, Any]] = []\n        if tools is not None:\n            for tool in tools:\n                if isinstance(tool, str):\n                    # Handle built-in tool types\n                    self._add_builtin_tool(tool)\n                elif isinstance(tool, dict) and \"type\" in tool:\n                    # Handle configured built-in tools\n                    self._tools.append(cast(dict[str, Any], tool))\n                else:\n                    raise ValueError(f\"Unsupported tool type: {type(tool)}\")\n\n    def _add_builtin_tool(self, tool_name: str) -> None:\n        \"\"\"Add a built-in tool by name.\"\"\"\n        # Skip if an identical tool has already been registered (idempotent behaviour)\n        if any(td.get(\"type\") == tool_name for td in self._tools):\n            return  # Duplicate – ignore rather than raise to stay backward-compatible\n        # Only allow string format for tools that don't require parameters\n        if tool_name == \"web_search_preview\":\n            self._tools.append({\"type\": \"web_search_preview\"})\n        elif tool_name == \"image_generation\":\n            self._tools.append({\"type\": \"image_generation\"})\n        elif tool_name == \"local_shell\":\n            # Special handling for local_shell - very limited model support\n            if self._model != \"codex-mini-latest\":\n                raise ValueError(\n                    f\"Tool 'local_shell' is only supported with model 'codex-mini-latest', \"\n                    f\"but current model is '{self._model}'. \"\n                    f\"This tool is available exclusively through the Responses API and has severe limitations. \"","sourceCodeStart":415,"sourceCodeEnd":451,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/agents/openai/_openai_agent.py#L415-L451","documentation":"OpenAIAgent's constructor validates each entry in the tools list: it accepts plain strings (built-in tool names) and dicts that contain a 'type' key (pre-configured tool payloads). Anything else — an int, a Tool instance, a function, a dict without 'type' — hits the else branch and raises ValueError with the offending type.","triggerScenarios":"Passing tools=[some_python_function] or tools=[FunctionTool(...)] (autogen-core tool objects) to OpenAIAgent; passing a dict like {\"function\": {...}} that lacks the \"type\" key; passing None inside the list.","commonSituations":"Copy-pasting a tools list from OpenAIAssistantAgent (which DOES accept Tool/callable objects) into OpenAIAgent; mixing autogen-core Tool instances with the Responses-API dict format; malformed JSON loaded tool configs missing the type field.","solutions":["Use string names for parameterless built-ins: tools=[\"web_search_preview\", \"image_generation\"].","Use full dict configuration for parameterized tools: tools=[{\"type\": \"file_search\", \"vector_store_ids\": [\"vs_...\"]}].","If you want an LLM to call Python functions, do not put them in tools=; use the tool schema produced by your ChatCompletionClient / function-calling setup instead."],"exampleFix":"# before\nagent = OpenAIAgent(\n    name=\"a\",\n    model=\"gpt-4o\",\n    client=client,\n    tools=[my_python_function],  # ValueError: Unsupported tool type: <class 'function'>\n)\n\n# after (built-in via string, configured tool via dict)\nagent = OpenAIAgent(\n    name=\"a\",\n    model=\"gpt-4o\",\n    client=client,\n    tools=[\n        \"web_search_preview\",\n        {\"type\": \"file_search\", \"vector_store_ids\": [\"vs_123\"]},\n    ],\n)","handlingStrategy":"validation","validationCode":"def is_valid_openai_agent_tool(tool: object) -> bool:\n    if isinstance(tool, str):\n        return True\n    return isinstance(tool, dict) and \"type\" in tool\n\nassert all(is_valid_openai_agent_tool(t) for t in tools)","typeGuard":"from typing import Any\n\ndef is_agent_tool(t: Any) -> bool:\n    return isinstance(t, str) or (isinstance(t, dict) and \"type\" in t)","tryCatchPattern":null,"preventionTips":["Keep two tool vocabularies separate: strings/dicts for OpenAIAgent, Tool/callables for OpenAIAssistantAgent.","Never pass autogen-core Tool instances or raw functions in OpenAIAgent's tools list.","Validate tool lists in one place before constructing agents."],"tags":["openai","tools","validation","responses-api"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}