microsoft/autogen · error · ValueError
Tools cannot be used with a workbench.
Error message
Tools cannot be used with a workbench.
What it means
AssistantAgent supports either explicit tools or a workbench, not both: when workbench is not None and any tools were registered, construction raises ValueError. Without a workbench the tools are implicitly wrapped in a StaticStreamWorkbench, so a workbench replaces the tool pathway entirely.
Source
Thrown at python/packages/autogen-agentchat/src/autogen_agentchat/agents/_assistant_agent.py:829
handoff_tool_names_set = set(handoff_tool_names)
# Check if there's any overlap between handoff tool names and tool names
overlap = tool_names_set.intersection(handoff_tool_names_set)
# Also check if any handoff target name matches a tool name
# This handles the case where a handoff is specified directly with a string that matches a tool name
for handoff in handoffs or []:
if isinstance(handoff, str) and handoff in tool_names_set:
raise ValueError("Handoff names must be unique from tool names")
elif isinstance(handoff, HandoffBase) and handoff.target in tool_names_set:
raise ValueError("Handoff names must be unique from tool names")
if overlap:
raise ValueError("Handoff names must be unique from tool names")
if workbench is not None:
if self._tools:
raise ValueError("Tools cannot be used with a workbench.")
if isinstance(workbench, Sequence):
self._workbench = workbench
else:
self._workbench = [workbench]
else:
self._workbench = [StaticStreamWorkbench(self._tools)]
if model_context is not None:
self._model_context = model_context
else:
self._model_context = UnboundedChatCompletionContext()
if self._output_content_type is not None and reflect_on_tool_use is None:
# If output_content_type is set, we need to reflect on tool use by default.
self._reflect_on_tool_use = True
elif reflect_on_tool_use is None:
self._reflect_on_tool_use = False
else:View on GitHub (pinned to 027ecf0a37)
Solutions
- Remove the tools argument when supplying a workbench; register tools on the workbench instead (e.g. StaticStreamWorkbench(tools)).
- Or drop the workbench and keep plain tools.
- Check that defaults are not silently injecting tools (tools=None is fine; only non-empty lists conflict).
Example fix
# before agent = AssistantAgent(name="a", model_client=client, tools=[my_tool], workbench=MyWorkbench()) # after agent = AssistantAgent(name="a", model_client=client, workbench=StaticStreamWorkbench([my_tool]))
Defensive patterns
Strategy: validation
Validate before calling
if tools and workbench is not None:
raise ValueError("pass either tools= or workbench=, not both") Try / catch
try:
agent = AssistantAgent(name="a", model_client=client, tools=tools, workbench=workbench)
except ValueError as e:
if "cannot be used with a workbench" in str(e):
agent = AssistantAgent(name="a", model_client=client, workbench=workbench) # tools live in the workbench
else:
raise Prevention
- Choose one tool-provisioning mechanism per agent and enforce it in a builder function.
- When migrating to workbenches, delete the tools= argument in the same change.
When it happens
Trigger: AssistantAgent(tools=[my_tool], workbench=MyWorkbench()) or (tools=[...], workbench=[wb1, wb2]) — any non-empty tools list plus a workbench argument.
Common situations: Migrating code that passed tools and then adding a workbench for tool-use streaming support without removing the tools parameter; copy-pasting examples that mix both APIs.
Related errors
- The model does not support function calling.
- Unsupported tool type: {type(tool)}
- Tool names must be unique: {tool_names}
- Handoff names must be unique from tool names
- Expected Memory, List[Memory], or None, got {type(memory)}
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/77335074b8dfa846.
Report an issue: GitHub.