{"record":{"id":"29707e9d357316ea","repo":"langchain-ai/langchain","slug":"structuredtool-does-not-support-sync-invocation","errorCode":null,"errorMessage":"StructuredTool does not support sync invocation.","messagePattern":"StructuredTool does not support sync invocation\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/tools/structured.py","lineNumber":99,"sourceCode":"        \"\"\"Use the tool.\n\n        Args:\n            *args: Positional arguments to pass to the tool\n            config: Configuration for the run\n            run_manager: Optional callback manager to use for the run\n            **kwargs: Keyword arguments to pass to the tool\n\n        Returns:\n            The result of the tool execution\n        \"\"\"\n        if self.func:\n            if run_manager and signature(self.func).parameters.get(\"callbacks\"):\n                kwargs[\"callbacks\"] = run_manager.get_child()\n            if config_param := _get_runnable_config_param(self.func):\n                kwargs[config_param] = config\n            return self.func(*args, **kwargs)\n        msg = \"StructuredTool does not support sync invocation.\"\n        raise NotImplementedError(msg)\n\n    async def _arun(\n        self,\n        *args: Any,\n        config: RunnableConfig,\n        run_manager: AsyncCallbackManagerForToolRun | None = None,\n        **kwargs: Any,\n    ) -> Any:\n        \"\"\"Use the tool asynchronously.\n\n        Args:\n            *args: Positional arguments to pass to the tool\n            config: Configuration for the run\n            run_manager: Optional callback manager to use for the run\n            **kwargs: Keyword arguments to pass to the tool\n\n        Returns:\n            The result of the tool execution","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/tools/structured.py#L81-L117","documentation":"Identical contract to Tool: StructuredTool._run raises NotImplementedError when only a coroutine was supplied. The structured schema exists, but there is no sync function, so .invoke/.run cannot execute the tool.","triggerScenarios":"StructuredTool.from_function(coroutine=async_fn) then tool.invoke({...}); agent/ToolNode driven synchronously (agent.invoke) with async-only StructuredTools.","commonSituations":"Async-native integrations (DB, HTTP tools) used inside sync notebook scripts; mixing sync agent runners with async tools; frameworks calling tool.func directly.","solutions":["Run the workflow asynchronously: await tool.ainvoke(...) / await agent.ainvoke(...)","Add a sync func implementation (or a bridge) alongside coroutine","If a third-party tool is async-only, wrap it: StructuredTool.from_function(func=lambda **kw: asyncio.run(async_fn(**kw)), coroutine=async_fn, ...)"],"exampleFix":"# before\nasync def fetch(url: str) -> str: ...\ntool = StructuredTool.from_function(coroutine=fetch, name=\"fetch\", description=\"Fetch\")\ntool.invoke({\"url\": \"https://x\"})  # NotImplementedError\n\n# after\nresult = asyncio.run(tool.ainvoke({\"url\": \"https://x\"}))","handlingStrategy":"type-guard","validationCode":"def call_tool(tool, payload):\n    if getattr(tool, \"func\", None) is not None:\n        return tool.invoke(payload)\n    import asyncio\n    return asyncio.run(tool.ainvoke(payload))","typeGuard":"def is_sync_tool(tool: object) -> bool:\n    return callable(getattr(tool, \"func\", None))","tryCatchPattern":"try:\n    out = tool.invoke(payload)\nexcept NotImplementedError as e:\n    if \"sync invocation\" in str(e):\n        out = asyncio.run(tool.ainvoke(payload))\n    else:\n        raise","preventionTips":["Run agents/tool nodes asynchronously when any tool is async-only","Ship both func and coroutine for tools in shared libraries","Check tool.func before choosing sync loops in frameworks"],"tags":["langchain","tools","async","structured-tool","not-implemented"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}