langchain-ai/deepagents · error · ExtensionError

Registered middleware must be an AgentMiddleware, got {kind}

Error message

Registered middleware must be an AgentMiddleware, got {kind}

What it means

After constructing the value, `register_middleware` verifies the instance is an `AgentMiddleware` (checked at runtime against `langchain.agents.middleware.types.AgentMiddleware`). Anything else — a plain object, a callable, a tool, or a wrapper — is rejected with `ExtensionError` naming the offending type. This keeps only contract-compliant middleware on the agent.

Source

Thrown at libs/code/deepagents_code/extensions/api.py:116

        Args:
            middleware: Middleware class or instance.

        Raises:
            ExtensionError: If `middleware` is invalid or cannot be constructed.
        """
        self._ensure_active()
        from langchain.agents.middleware.types import AgentMiddleware

        try:
            instance = middleware() if isinstance(middleware, type) else middleware
        except Exception as exc:
            msg = f"Could not construct middleware {middleware!r}: {exc}"
            raise ExtensionError(msg) from exc
        if not isinstance(instance, AgentMiddleware):
            kind = type(instance).__name__
            msg = f"Registered middleware must be an AgentMiddleware, got {kind}"
            raise ExtensionError(msg)
        self._registry.add_middleware(instance, self._source)

    def register_tool(self, tool: BaseTool | Callable[..., Any]) -> None:
        """Expose an LLM-callable tool.

        Plain callables are converted using LangChain's tool schema inference.

        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)

View on GitHub (pinned to a1af029e6e)

Solutions

  1. Subclass `AgentMiddleware` from `langchain.agents.middleware.types` for custom middleware.
  2. Use `api.register_tool(...)` for tools/callables, not `register_middleware`.
  3. Verify `isinstance(obj, AgentMiddleware)` in the extension before registering; update the langchain pin if the base class moved.
  4. If wrapping a third-party object, adapt it into an `AgentMiddleware` subclass.

Example fix

# before
class MyHook:
    ...
api.register_middleware(MyHook())

# after
from langchain.agents.middleware.types import AgentMiddleware
class MyHook(AgentMiddleware):
    ...
api.register_middleware(MyHook())
Defensive patterns

Strategy: type-guard

Validate before calling

from langchain.agents.middleware.types import AgentMiddleware

def assert_agent_middleware(obj) -> None:
    if not isinstance(obj, AgentMiddleware):
        raise TypeError(f"{type(obj).__name__} is not an AgentMiddleware")

Type guard

def is_agent_middleware(obj) -> bool:
    return isinstance(obj, AgentMiddleware)

Try / catch

try:
    api.register_middleware(candidate)
except ExtensionError as exc:
    if "must be an AgentMiddleware" in str(exc):
        logger.error("wrong registration API for %s; use register_tool for tools", candidate)
    else:
        raise

Prevention

When it happens

Trigger: Registering an arbitrary object or function that duck-types middleware but does not subclass `AgentMiddleware`; passing a `BaseTool` or callable to `register_middleware` instead of `register_tool`; inheriting from the wrong base class after a LangChain refactor.

Common situations: Confusion between `register_tool` and `register_middleware` when wiring custom hooks; custom middleware extending a deprecated base whose class no longer subclasses `AgentMiddleware`; LangChain version upgrade moving/renaming the middleware hierarchy.

Related errors


AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29). Data as JSON: /api/errors/0c20e5f5c2ae71e6. Report an issue: GitHub.