langchain-ai/deepagents · error · ExtensionError
Could not convert {name} into a tool: {exc}
Error message
Could not convert {name} into a tool: {exc} What it means
Raised by ExtensionApi.register_tool when `as_tool()` cannot turn the supplied callable into a LangChain tool. The original conversion failure is chained as __cause__ and the tool's name is included in the message. It signals that the function's signature, docstring, or annotations are unsuitable for automatic tool conversion.
Source
Thrown at libs/code/deepagents_code/extensions/api.py:141
Args:
tool: Tool instance or plain callable.
Raises:
ExtensionError: If a callable cannot be converted into a tool.
"""
self._ensure_active()
from langchain_core.tools import BaseTool, tool as as_tool
if isinstance(tool, BaseTool):
self._registry.add_tool(tool, self._source)
return
try:
converted = as_tool(tool)
except Exception as exc:
name = getattr(tool, "__name__", repr(tool))
msg = f"Could not convert {name} into a tool: {exc}"
raise ExtensionError(msg) from exc
self._registry.add_tool(converted, self._source) # type: ignore[arg-type] # callable overload returns BaseTool
def register_backend_route(self, prefix: str, backend: BackendProtocol) -> None:
"""Mount a backend under a virtual filesystem path.
File operations under `prefix` are routed to `backend` by the agent's
`CompositeBackend`. Shell execution remains on the default backend and
cannot access routed virtual content.
Args:
prefix: Lowercase absolute path ending in `/`, such as `/memories/`.
backend: Backend serving file operations under the prefix.
Raises:
ExtensionError: If the prefix or backend is invalid.
"""
self._ensure_active()
from deepagents.backends.protocol import BackendProtocolView on GitHub (pinned to a1af029e6e)
Solutions
- Read the chained __cause__ exception to see why as_tool failed
- Add complete, JSON-serializable type annotations to every parameter and the return value of the function
- Ensure the function has a usable name (__name__) and a docstring describing its behavior
- If the callable cannot satisfy as_tool, wrap it in a plain function or build the tool explicitly instead of relying on automatic conversion
- Verify the object being registered is actually a callable function, not an arbitrary object
Example fix
// before
ext.register_tool(some_builtin_open)
// after
def open_file(path: str) -> str:
"""Open a file and return its contents."""
return Path(path).read_text()
ext.register_tool(open_file) Defensive patterns
Strategy: validation
Validate before calling
import inspect
def can_register(fn) -> bool:
if not callable(fn) or not hasattr(fn, "__name__"):
return False
try:
return inspect.signature(fn) is not None
except (TypeError, ValueError):
return False
if not can_register(my_func):
raise ValueError("function lacks introspectable signature/annotations") Type guard
def is_tool_candidate(fn: object) -> bool:
return callable(fn) and hasattr(fn, "__name__") and hasattr(fn, "__doc__") Try / catch
try:
ext.register_tool(my_func)
except ExtensionError as exc:
logger.error("tool registration failed for %s: %s", my_func, exc.__cause__) Prevention
- Always annotate all parameters and return type with JSON-serializable types
- Write a docstring on every function you register as a tool
- Test tool registration in unit tests before shipping the extension
When it happens
Trigger: Calling `ext.register_tool(fn)` where fn lacks a resolvable signature, has annotations the tool converter cannot handle (e.g. unsupported/missing type hints), or raises during argument-schema generation inside `as_tool`.
Common situations: Registering a builtin or C function without introspectable signatures; a function with untyped or exotic-typed parameters (unions of non-JSON types, arbitrary objects); registering an object that is not a plain function.
Related errors
- Extension registration is closed for this session
- Could not construct middleware {middleware!r}: {exc}
- Registered middleware must be an AgentMiddleware, got {kind}
- Invalid backend route prefix {prefix!r}: use lowercase path
- Backend route {prefix!r} got {type(backend).__name__}, which
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/b77dfd0aff80d1f0.
Report an issue: GitHub.