{"record":{"id":"1461d9bd712cc426","repo":"microsoft/autogen","slug":"model-does-not-support-function-calling-and-tools","errorCode":null,"errorMessage":"Model does not support function calling and tools were provided","messagePattern":"Model does not support function calling and tools were provided","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-ext/src/autogen_ext/models/ollama/_ollama_client.py","lineNumber":586,"sourceCode":"            # Remove format from create_args to prevent passing it twice.\n            del create_args[\"format\"]\n\n        # TODO: allow custom handling.\n        # For now we raise an error if images are present and vision is not supported\n        if self.model_info[\"vision\"] is False:\n            for message in messages:\n                if isinstance(message, UserMessage):\n                    if isinstance(message.content, list) and any(isinstance(x, Image) for x in message.content):\n                        raise ValueError(\"Model does not support vision and image was provided\")\n\n        if self.model_info[\"json_output\"] is False and json_output is True:\n            raise ValueError(\"Model does not support JSON output.\")\n\n        ollama_messages_nested = [to_ollama_type(m) for m in messages]\n        ollama_messages = [item for sublist in ollama_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 and tools were provided\")\n\n        converted_tools: List[OllamaTool] = []\n\n        # Handle tool_choice parameter in a way that is compatible with Ollama API.\n        if isinstance(tool_choice, Tool):\n            # If tool_choice is a Tool, convert it to OllamaTool.\n            converted_tools = convert_tools([tool_choice])\n        elif tool_choice == \"none\":\n            # No tool choice, do not pass tools to the API.\n            converted_tools = []\n        elif tool_choice == \"required\":\n            # Required tool choice, pass tools to the API.\n            converted_tools = convert_tools(tools)\n            if len(converted_tools) == 0:\n                raise ValueError(\"tool_choice 'required' specified but no tools provided\")\n        else:\n            converted_tools = convert_tools(tools)\n","sourceCodeStart":568,"sourceCodeEnd":604,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/models/ollama/_ollama_client.py#L568-L604","documentation":"OllamaChatCompletionClient pre-flight checks function-calling capability. If model_info['function_calling'] is False and a non-empty tools list is passed to create()/create_stream(), it raises ValueError rather than forwarding tools to Ollama. This guards against silent tool-ignoring behavior on models without tool support.","triggerScenarios":"Calling create(messages, tools=[...]) with a non-empty tools sequence while model_info['function_calling'] is False — typical when the model is unknown to the client or model_info was supplied without the function_calling flag.","commonSituations":"Running a tool-using agent (e.g. AssistantAgent with tools) against a local model like llama2 or an uncached model name; hand-written model_info missing the 'function_calling' key defaults it to False; upgrading autogen-ext so a previously-tolerated model name now resolves differently.","solutions":["Use a tool-capable model (llama3.1, qwen2.5, mistral-nemo) and pass model_info with 'function_calling': True","Remove the tools argument when the model genuinely cannot call functions","If calling manually, register tools as prompt text instead and parse the model's reply yourself (last resort)"],"exampleFix":"# before\nclient = OllamaChatCompletionClient(model='qwen2.5:7b')\nawait client.create(messages, tools=[{'type':'function','function':{...}}])  # ValueError\n\n# after\nclient = OllamaChatCompletionClient(\n    model='qwen2.5:7b',\n    model_info={'vision': False, 'function_calling': True, 'json_output': True, 'family': ModelFamily.UNKNOWN, 'structured_output': False},\n)\nawait client.create(messages, tools=[...])","handlingStrategy":"validation","validationCode":"tools_ok = bool(client.model_info.get('function_calling', False))\nif tools:\n    assert tools_ok, f'Model {client._model_name!r} cannot call functions; drop tools or change model'\nresult = await client.create(messages, tools=tools if tools_ok else [])","typeGuard":"def supports_tools(model_info: dict) -> bool:\n    return model_info.get('function_calling') is True","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)  # degrade to no-tools turn\n    else:\n        raise","preventionTips":["Pass model_info with 'function_calling': True when using a tool-capable local model","Gate agent tool registration on the model's declared capabilities","Smoke-test create() with tools when switching Ollama models"],"tags":["ollama","function-calling","tools","validation","autogen"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}