{"record":{"id":"d9c37ce8223049fc","repo":"langchain-ai/deepagents","slug":"could-not-construct-middleware-middleware-r-ex","errorCode":null,"errorMessage":"Could not construct middleware {middleware!r}: {exc}","messagePattern":"Could not construct middleware (.+?): (.+?)","errorType":"exception","errorClass":"ExtensionError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/extensions/api.py","lineNumber":112,"sourceCode":"        \"\"\"Install LangChain middleware on the agent.\n\n        A class is instantiated without arguments. Pass an instance when\n        construction requires configuration.\n\n        Args:\n            middleware: Middleware class or instance.\n\n        Raises:\n            ExtensionError: If `middleware` is invalid or cannot be constructed.\n        \"\"\"\n        self._ensure_active()\n        from langchain.agents.middleware.types import AgentMiddleware\n\n        try:\n            instance = middleware() if isinstance(middleware, type) else middleware\n        except Exception as exc:\n            msg = f\"Could not construct middleware {middleware!r}: {exc}\"\n            raise ExtensionError(msg) from exc\n        if not isinstance(instance, AgentMiddleware):\n            kind = type(instance).__name__\n            msg = f\"Registered middleware must be an AgentMiddleware, got {kind}\"\n            raise ExtensionError(msg)\n        self._registry.add_middleware(instance, self._source)\n\n    def register_tool(self, tool: BaseTool | Callable[..., Any]) -> None:\n        \"\"\"Expose an LLM-callable tool.\n\n        Plain callables are converted using LangChain's tool schema inference.\n\n        Args:\n            tool: Tool instance or plain callable.\n\n        Raises:\n            ExtensionError: If a callable cannot be converted into a tool.\n        \"\"\"\n        self._ensure_active()","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/extensions/api.py#L94-L130","documentation":"`register_middleware` accepts either an `AgentMiddleware` class or instance. A class is instantiated with no arguments; if that constructor call (or any construction path) raises, the error is wrapped in `ExtensionError` with the middleware repr and original message. This surfaces constructor problems (missing required args, import failures, bad config) at registration time with provenance.","triggerScenarios":"Registering a middleware class whose `__init__` requires arguments; a class whose `__init__` raises (network init, missing dependency, invalid config); passing a factory callable that is not a class but truthy as a type.","commonSituations":"Third-party middleware requiring a constructor parameter in a newer version; a middleware importing an optional dependency that is not installed; config-driven middleware built with required fields left unset.","solutions":["Pass a configured instance instead of a bare class: `api.register_middleware(MyMiddleware(required_arg=...))`.","Fix the underlying exception shown after the colon (missing arg, missing dependency, bad config).","Ensure a no-arg constructor exists if you intend to register the class itself.","Wrap construction in a try/except in the extension factory to log and degrade gracefully."],"exampleFix":"# before\napi.register_middleware(RetryMiddleware)  # __init__ requires max_retries\n\n# after\napi.register_middleware(RetryMiddleware(max_retries=3))\n","handlingStrategy":"try-catch","validationCode":"def middleware_instantiates(mw) -> bool:\n    if isinstance(mw, type):\n        try:\n            mw()\n            return True\n        except Exception:\n            return False\n    return True  # already an instance\n","typeGuard":"def is_instantiable_middleware_class(mw) -> bool:\n    return isinstance(mw, type) and issubclass(mw, AgentMiddleware)\n","tryCatchPattern":"try:\n    api.register_middleware(MyMiddleware)\nexcept ExtensionError as exc:\n    logger.error(\"middleware registration failed: %s\", exc)\n    api.register_middleware(MyMiddleware(required=config_value))  # fallback: pass config\n","preventionTips":["Pass configured instances when the constructor needs arguments.","Keep middleware constructors dependency-light and no-arg where possible.","Validate required config in the extension factory before registering.","Log-and-degrade in the factory so one bad middleware does not kill the session."],"tags":["extensions","middleware","instantiation"],"backgroundTag":"middleware-construction-failed","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}