microsoft/autogen · error · ValueError

No tools are available.

Error message

No tools are available.

What it means

OpenAIAssistantAgent._execute_tool_call refuses to process any FunctionCall when self._original_tools is empty. The assistant-side tool set must have been supplied at construction (strings, Tool instances, or callables); with none registered there is nothing to bind a tool call to, which indicates a configuration bug rather than a model hiccup.

Source

Thrown at python/packages/autogen-ext/src/autogen_ext/agents/openai/_openai_assistant_agent.py:387

    def messages(self) -> AsyncMessages:
        return self._client.beta.threads.messages

    @property
    def _get_assistant_id(self) -> str:
        if self._assistant is None:
            raise ValueError("Assistant not initialized")
        return self._assistant.id

    @property
    def _thread_id(self) -> str:
        if self._thread is None:
            raise ValueError("Thread not initialized")
        return self._thread.id

    async def _execute_tool_call(self, tool_call: FunctionCall, cancellation_token: CancellationToken) -> str:
        """Execute a tool call and return the result."""
        if not self._original_tools:
            raise ValueError("No tools are available.")
        tool = next((t for t in self._original_tools if t.name == tool_call.name), None)
        if tool is None:
            raise ValueError(f"The tool '{tool_call.name}' is not available.")
        arguments = json.loads(tool_call.arguments)
        result = await tool.run_json(arguments, cancellation_token, call_id=tool_call.id)
        return tool.return_value_as_string(result)

    async def on_messages(self, messages: Sequence[BaseChatMessage], cancellation_token: CancellationToken) -> Response:
        """Handle incoming messages and return a response."""

        async for message in self.on_messages_stream(messages, cancellation_token):
            if isinstance(message, Response):
                return message
        raise AssertionError("The stream should have returned the final result.")

    async def on_messages_stream(
        self, messages: Sequence[BaseChatMessage], cancellation_token: CancellationToken
    ) -> AsyncGenerator[BaseAgentEvent | BaseChatMessage | Response, None]:

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Pass the matching Tool/Callable implementations in tools= when constructing the agent.
  2. When attaching to an existing assistant_id, make sure the local tool set mirrors the functions defined on the server-side assistant.
  3. If the assistant should not call tools, remove the function tools from the OpenAI assistant definition (update via the API) so runs never enter requires_action.

Example fix

# before
agent = OpenAIAssistantAgent(name="a", instructions="...", model="gpt-4o",
                            client=cl, assistant_id="asst_with_tools")
# asst_with_tools has server-side function tools -> run hits requires_action -> error

# after
agent = OpenAIAssistantAgent(
    name="a", instructions="...", model="gpt-4o", client=cl,
    assistant_id="asst_with_tools",
    tools=[get_weather, FunctionTool(search_docs, description="Search docs")],
)
Defensive patterns

Strategy: validation

Validate before calling

if not agent._original_tools:  # after construction
    raise ConfigError("Register tools before runs that may require_action")

Prevention

When it happens

Trigger: Constructing the agent with tools=[] or tools=None, then the Assistants API somehow returning a requires_action run with function tool calls (e.g. the assistant_id points to a pre-existing OpenAI assistant that HAS server-side tools, while the local agent has none registered).

Common situations: Reusing an existing assistant_id whose server-side definition includes function tools, but constructing the local agent without the matching Tool implementations; deleting tools locally but not on the OpenAI side.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/da517b631da20dda. Report an issue: GitHub.