{"record":{"id":"39f164ee720a7530","repo":"langchain-ai/deepagents","slug":"cannot-create-an-mcp-session-after-cleanup","errorCode":null,"errorMessage":"Cannot create an MCP session after cleanup","messagePattern":"Cannot create an MCP session after cleanup","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/mcp_tools.py","lineNumber":779,"sourceCode":"            self._locks[server_name] = lock\n        return lock\n\n    async def _create_entry(self, server_name: str) -> _MCPSessionEntry:\n        \"\"\"Create and initialize a new cached session entry.\n\n        Args:\n            server_name: MCP server name.\n\n        Returns:\n            A cached session entry containing the live session and close stack.\n\n        Raises:\n            RuntimeError: If the manager has already been cleaned up.\n            ValueError: If `server_name` is not configured in the manager.\n        \"\"\"\n        if self._closed:\n            msg = \"Cannot create an MCP session after cleanup\"\n            raise RuntimeError(msg)\n\n        try:\n            connection = self._connections[server_name]\n        except KeyError as exc:\n            msg = (\n                f\"Couldn't find an MCP server named '{server_name}', \"\n                f\"expected one of {sorted(self._connections)}\"\n            )\n            raise ValueError(msg) from exc\n\n        exit_stack = AsyncExitStack()\n        try:\n            session = await exit_stack.enter_async_context(\n                _create_mcp_session(connection, server_name=server_name)\n            )\n            await session.initialize()\n        except BaseException:\n            # Close the partially entered stack in *this* task before","sourceCodeStart":761,"sourceCodeEnd":797,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/mcp_tools.py#L761-L797","documentation":"_create_entry (invoked lazily by get_session) raises RuntimeError if the manager was closed, since no new sessions can be created after cleanup.","triggerScenarios":"Calling get_session(server_name) after close()/cleanup; holding a manager reference past app shutdown and reusing it.","commonSituations":"Background tasks or request handlers still using a manager that a shutdown hook already closed; tests tearing down fixtures while coroutines are pending.","solutions":["Recreate the manager and reconfigure it before calling get_session","Ensure all get_session calls complete before close()","Guard get_session behind a manager-open check"],"exampleFix":"// before\nawait manager.close()\nawait manager.get_session('fs')  # raises\n// after\nawait manager.close()\nmanager = MCPSessionManager()\nawait manager.configure(connections)\nawait manager.get_session('fs')","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    session = await manager.get_session(server)\nexcept RuntimeError as e:\n    if 'after cleanup' in str(e):\n        manager = MCPSessionManager()\n        await manager.configure(connections)\n        session = await manager.get_session(server)\n    else:\n        raise","preventionTips":["Cancel background tasks before closing the manager","Use an async context manager (async with) so use and cleanup are scoped","Do not retain manager references past shutdown"],"tags":["mcp","lifecycle","runtime-error"],"backgroundTag":"manager-already-closed","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}