{"record":{"id":"0d7a82aa15e9ab95","repo":"microsoft/autogen","slug":"model-does-not-support-function-calling-0d7a82","errorCode":null,"errorMessage":"Model does not support function calling","messagePattern":"Model does not support function calling","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-ext/src/autogen_ext/models/openai/_openai_client.py","lineNumber":629,"sourceCode":"        if create_args.get(\"model\", \"unknown\").startswith(\"claude-\"):\n            # When Claude models last message is AssistantMessage, It could not end with whitespace\n            messages = self._rstrip_last_assistant_message(messages)\n\n        oai_messages_nested = [\n            to_oai_type(\n                m,\n                prepend_name=self._add_name_prefixes,\n                model=create_args.get(\"model\", \"unknown\"),\n                model_family=self._model_info[\"family\"],\n                include_name_in_message=self._include_name_in_message,\n            )\n            for m in messages\n        ]\n\n        oai_messages = [item for sublist in oai_messages_nested for item in sublist]\n\n        if self.model_info[\"function_calling\"] is False and len(tools) > 0:\n            raise ValueError(\"Model does not support function calling\")\n\n        converted_tools = convert_tools(tools)\n\n        # Process tool_choice parameter\n        if isinstance(tool_choice, Tool):\n            if len(tools) == 0:\n                raise ValueError(\"tool_choice specified but no tools provided\")\n\n            # Validate that the tool exists in the provided tools\n            tool_names_available: List[str] = []\n            for tool in tools:\n                if isinstance(tool, Tool):\n                    tool_names_available.append(tool.schema[\"name\"])\n                else:\n                    tool_names_available.append(tool[\"name\"])\n\n            # tool_choice is a single Tool object\n            tool_name = tool_choice.schema[\"name\"]","sourceCodeStart":611,"sourceCodeEnd":647,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/models/openai/_openai_client.py#L611-L647","documentation":"Thrown by OpenAIChatCompletionClient when tools are passed to create/create_stream but the client's model_info declares function_calling as False. The check runs after message conversion but before tools are converted, failing client-side. It prevents sending tool schemas to models that cannot invoke functions.","triggerScenarios":"Calling create with a non-empty tools=[...] (Tool or ToolSchema objects) while model_info['function_calling'] is False, e.g. a legacy or custom model without tool support. This also fires for agents like ToolAvailChatAgent or function-calling workflows that always register tools.","commonSituations":"Running a tool-using agent (e.g. AssistantAgent with tools/workbench) against a model with an incomplete custom model_info; using small open-weights models that lack function calling; model_info dicts written before function_calling became a standard key.","solutions":["Use a function-calling-capable model (e.g. gpt-4o) whose model_info has function_calling=True","If the backend does support tools, correct the model_info dict passed to the constructor to set 'function_calling': True","Remove tools from the call and rely on prompt-based tool selection if the model cannot call functions"],"exampleFix":"# before\nclient = OpenAIChatCompletionClient(model=\"my-model\", model_info={\"vision\": False, \"function_calling\": False, \"json_output\": False, \"family\": \"unknown\"})\nawait client.create([msg], tools=[get_weather_tool])\n\n# after\nclient = OpenAIChatCompletionClient(model=\"my-model\", model_info={\"vision\": False, \"function_calling\": True, \"json_output\": False, \"family\": \"unknown\"})\nawait client.create([msg], tools=[get_weather_tool])","handlingStrategy":"validation","validationCode":"if tools and not client.info.get(\"function_calling\", False):\n    tools = []  # or raise / switch model\n    tool_choice = \"none\"","typeGuard":"def supports_tools(client, tools) -> bool:\n    return len(tools) == 0 or bool(client.info.get(\"function_calling\", False))","tryCatchPattern":"try:\n    result = await client.create(messages, tools=tools)\nexcept ValueError as e:\n    if \"function calling\" in str(e):\n        result = await client.create(messages)  # toolless fallback\n    else:\n        raise","preventionTips":["Gate tool registration on client.info['function_calling'] in agent setup code","Keep custom model_info dicts complete (function_calling, vision, json_output, family) in one shared module","Smoke-test each new model with a one-tool call before wiring full agents"],"tags":["openai","function-calling","tools","validation","model-info"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}