{"record":{"id":"b9579f69368c46d8","repo":"PrefectHQ/fastmcp","slug":"fastmcp-instance-is-no-longer-available-b9579f","errorCode":null,"errorMessage":"FastMCP instance is no longer available","messagePattern":"FastMCP instance is no longer available","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/low_level.py","lineNumber":511,"sourceCode":"        # the server was constructed without an explicit `request_state_security`\n        # policy, seal under a per-process ephemeral key (single-process\n        # deployments); multi-replica deployments pass a shared-key policy. The\n        # low-level server always has a name (FastMCP autogenerates one), so the\n        # audience claim is always populated.\n        security = fastmcp._request_state_security or RequestStateSecurity.ephemeral()\n        self.middleware.append(\n            cast(\n                \"ServerMiddleware[LifespanResultT]\",\n                RequestStateBoundary(security, default_audience=self.name),\n            )\n        )\n\n    @property\n    def fastmcp(self) -> FastMCP:\n        \"\"\"Get the FastMCP instance.\"\"\"\n        fastmcp = self._fastmcp_ref()\n        if fastmcp is None:\n            raise RuntimeError(\"FastMCP instance is no longer available\")\n        return fastmcp\n\n    def create_initialization_options(\n        self,\n        notification_options: NotificationOptions | None = None,\n        experimental_capabilities: dict[str, dict[str, Any]] | None = None,\n        extensions: dict[str, dict[str, Any]] | None = None,\n    ) -> InitializationOptions:\n        # ensure we use the FastMCP notification options\n        if notification_options is None:\n            notification_options = self.notification_options\n        return super().create_initialization_options(\n            notification_options=notification_options,\n            experimental_capabilities=experimental_capabilities,\n            extensions=extensions,\n        )\n\n    def get_capabilities(","sourceCodeStart":493,"sourceCodeEnd":529,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/low_level.py#L493-L529","documentation":"LowLevelServer keeps only a weak reference (weakref.ref) to the FastMCP instance to avoid a circular reference (fastmcp_slim/fastmcp/server/low_level.py:459). The `fastmcp` property dereferences that weakref, and if the FastMCP object has been garbage collected it raises this RuntimeError instead of returning None. It is a lifecycle bug in user code, not an MCP protocol error: the low-level server outlived the FastMCP server it wraps.","triggerScenarios":"Accessing `server.fastmcp` (or any code path that touches it, e.g. `create_initialization_options`/`get_capabilities` via the experimental-capability merge) after the FastMCP instance has been garbage collected — typically when only the LowLevelServer was kept alive and the FastMCP object was never assigned to a long-lived variable.","commonSituations":"Scripts that build a FastMCP server inline (`LowLevelServer(FastMCP('demo'))` without storing the FastMCP instance); test suites where the FastMCP fixture goes out of scope while the session/server object persists; refactors that dropped a module-level or app-level reference to the server.","solutions":["Keep a strong, long-lived reference to the FastMCP instance (module-level variable, app state, or fixture) for as long as the LowLevelServer/session is alive.","Construct and store both objects together: `mcp = FastMCP('demo'); llm = LowLevelServer(mcp)` and keep `mcp` in scope.","If the reference must be dropped, also drop the LowLevelServer/session at the same time so no dangling dereference occurs.","Check for test-framework garbage collection (e.g. pytest fixtures that del the server) and use a session-scoped fixture to hold the FastMCP instance."],"exampleFix":"# before\nserver = LowLevelServer(FastMCP('demo'))  # FastMCP instance immediately unreachable\nrun(server)\n# after\nmcp = FastMCP('demo')          # strong reference kept alive\nserver = LowLevelServer(mcp)\nrun(server)","handlingStrategy":"type-guard","validationCode":"import weakref\nref = getattr(server, '_fastmcp_ref', None)\nif not isinstance(ref, weakref.ref) or ref() is None:\n    raise RuntimeError('FastMCP instance was garbage collected; recreate both objects')","typeGuard":"def fastmcp_alive(server) -> bool:\n    ref = getattr(server, '_fastmcp_ref', None)\n    return ref is not None and ref() is not None","tryCatchPattern":"try:\n    mcp = server.fastmcp\nexcept RuntimeError as e:\n    if 'no longer available' in str(e):\n        mcp = FastMCP('demo')  # recreate and keep a strong reference\n        server = LowLevelServer(mcp)\n    else:\n        raise","preventionTips":["Always assign the FastMCP instance to a long-lived variable before constructing LowLevelServer.","Use session-scoped fixtures in tests so the FastMCP object outlives the server/session.","Never construct LowLevelServer from a temporary expression like LowLevelServer(FastMCP('x')).","Check for explicit del or scoping bugs that drop the only reference to the FastMCP instance."],"tags":["python","lifecycle","weakref","garbage-collection"],"backgroundTag":"weakref-target-garbage-collected","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}