microsoft/autogen · error · AttributeError
The provided LangChain tool '{name}' does not have a callabl
Error message
The provided LangChain tool '{name}' does not have a callable 'func' or '_run' method. What it means
LangChainToolAdapter.__init__ inspects the wrapped LangChain tool for a callable 'func' attribute (StructuredTool-style) or '_run' method (BaseTool subclass). If neither is present/callable, AttributeError is raised with the tool's name. This typically happens with tools whose executable is exposed differently (e.g. coroutine-only StructuredTool) or tools that are pure declaration objects.
Source
Thrown at python/packages/autogen-ext/src/autogen_ext/tools/langchain/_langchain_adapter.py:159
asyncio.run(main())
"""
def __init__(self, langchain_tool: LangChainTool):
self._langchain_tool: LangChainTool = langchain_tool
# Extract name and description
name = self._langchain_tool.name
description = self._langchain_tool.description or ""
# Determine the callable method
if hasattr(self._langchain_tool, "func") and callable(self._langchain_tool.func): # type: ignore
assert self._langchain_tool.func is not None # type: ignore
self._callable: Callable[..., Any] = self._langchain_tool.func # type: ignore
elif hasattr(self._langchain_tool, "_run") and callable(self._langchain_tool._run): # type: ignore
self._callable: Callable[..., Any] = self._langchain_tool._run # type: ignore
else:
raise AttributeError(
f"The provided LangChain tool '{name}' does not have a callable 'func' or '_run' method."
)
# Determine args_type
if self._langchain_tool.args_schema: # pyright: ignore
args_type = self._langchain_tool.args_schema # pyright: ignore
else:
# Infer args_type from the callable's signature
sig = inspect.signature(cast(Callable[..., Any], self._callable)) # type: ignore
fields = {
k: (v.annotation, Field(...))
for k, v in sig.parameters.items()
if k != "self" and v.kind not in (inspect.Parameter.VAR_POSITIONAL, inspect.Parameter.VAR_KEYWORD)
}
args_type = create_model(f"{name}Args", **fields) # type: ignore
# Note: type ignore is used due to a LangChain typing limitation
# Ensure args_type is a subclass of BaseModelView on GitHub (pinned to 027ecf0a37)
Solutions
- Create the tool so a callable func exists: use @tool decorator on a sync function, or StructuredTool.from_function(fn).
- For async functions, decorate them with @tool anyway (the decorator wraps them and provides a runnable path), rather than hand-constructing StructuredTool with only coroutine.
- Check the LangChain version compatibility with the autogen-ext langchain extra; upgrade/downgrade langchain to a supported major version.
- Verify the object really is a BaseTool instance before adapting: isinstance(tool, BaseTool).
Example fix
# before
from langchain_core.tools import StructuredTool
tool = StructuredTool(
name="fetch",
description="fetch data",
coroutine=async_fetch, # func missing -> adapter raises
)
adapter = LangChainToolAdapter(tool)
# after
from langchain_core.tools import tool as lc_tool
@lc_tool
def fetch(q: str) -> str:
"""fetch data"""
return do_fetch(q)
adapter = LangChainToolAdapter(fetch) Defensive patterns
Strategy: type-guard
Validate before calling
fn = getattr(tool, "func", None)
run = getattr(tool, "_run", None)
if not (callable(fn) or callable(run)):
raise TypeError(f"tool {tool!r} exposes no callable func/_run; wrap it with @tool first") Type guard
from typing import Any, Callable, TypeGuard
def is_adaptable_langchain_tool(tool: Any) -> TypeGuard[Any]:
fn = getattr(tool, "func", None)
run = getattr(tool, "_run", None)
return callable(fn) or callable(run) Try / catch
try:
adapter = LangChainToolAdapter(tool)
except AttributeError as e:
raise TypeError(f"Cannot adapt {type(tool).__name__}: {e}") from e Prevention
- Always create tools with the @tool decorator or StructuredTool.from_function instead of hand-constructing StructuredTool.
- Check isinstance(tool, BaseTool) before adapting.
- Pin langchain-core to a tested major version in your lockfile.
When it happens
Trigger: Passing a LangChain tool to LangChainToolAdapter where tool.func is None/absent and tool._run is not callable — e.g. a StructuredTool built with only coroutine=..., since StructuredTool sets func to a placeholder raising NotImplementedError that may not be flagged callable-but-usable, or a mock/Pydantic model mistaken for a tool.
Common situations: Wrapping an async-only StructuredTool created via StructuredTool(coroutine=async_fn) in older langchain versions; passing a tool schema/dict from an agent framework rather than an actual tool instance; passing @tool-decorated object from an incompatible langchain major version where attributes moved; passing Mock objects in tests.
Related errors
- Failed to create a valid Pydantic v2 model for {name}
- Could not create chat manager
- Could not create chat manager; make sure that it contains a
- Failed to create instance of {input.FullName}
- No handler method found for interface {interface_.FullName}
AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15).
Data as JSON: /api/errors/4bcd146fa5808b45.
Report an issue: GitHub.