{"record":{"id":"0a0caf5f7bc8c02f","repo":"PrefectHQ/fastmcp","slug":"fastmcp-instance-is-no-longer-available","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/context.py","lineNumber":266,"sourceCode":"\n    @property\n    def origin_request_id(self) -> str | None:\n        \"\"\"Get the request ID that originated this execution, if available.\n\n        In foreground request mode, this is the current request_id.\n        In background task mode, this is the request_id captured when the task\n        was submitted, if one was available.\n        \"\"\"\n        if self.request_context is not None:\n            return str(self.request_context.request_id)\n        return self._origin_request_id\n\n    @property\n    def fastmcp(self) -> FastMCP:\n        \"\"\"Get the FastMCP instance.\"\"\"\n        fastmcp = self._fastmcp()\n        if fastmcp is None:\n            raise RuntimeError(\"FastMCP instance is no longer available\")\n        return fastmcp\n\n    async def __aenter__(self) -> Context:\n        \"\"\"Enter the context manager and set this context as the current context.\"\"\"\n        # Inherit request-scoped state from parent context so middleware\n        # and tool contexts share the same in-memory state dict.\n        parent = _current_context.get(None)\n        if parent is not None:\n            self._request_state = parent._request_state\n\n        # Always set this context and save the token\n        token = _current_context.set(self)\n        self._tokens.append(token)\n\n        # Set current server for dependency injection (use weakref to avoid reference cycles)\n        from fastmcp.server.dependencies import _current_server, is_docket_available\n\n        self._server_token = _current_server.set(weakref.ref(self.fastmcp))","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/context.py#L248-L284","documentation":"The Context.fastmcp property returns the FastMCP server instance via a weak/optional reference (self._fastmcp()). When the reference has been cleared — the server is gone or the Context outlived the request lifecycle — the property raises RuntimeError instead of returning None, forcing callers to handle the loss of the server explicitly.","triggerScenarios":"Accessing ctx.fastmcp on a Context whose backing request lifecycle has ended: e.g. holding a Context reference in a closure or background coroutine and reading .fastmcp after the request completes, or a Context created outside a server run.","commonSituations":"Background tasks or fire-and-forget asyncio tasks capturing ctx and touching it later; long-lived worker threads using a stale Context; tests instantiating Context directly without a bound server.","solutions":["Use the Context within the request that produced it; capture needed server data (settings, server name) before the request ends.","Check ctx.request_context (or the underlying reference) before touching .fastmcp in deferred code.","For background work, fetch the server via module-level imports or dependency functions instead of the Context.","If you only need it opportunistically, call self._fastmcp() equivalents defensively / wrap in try-except RuntimeError."],"exampleFix":"// before\nasync def tool(x: int, ctx: Context):\n    asyncio.create_task(later(ctx))  # ctx.fastmcp may be gone\n// after\nasync def tool(x: int, ctx: Context):\n    srv = ctx.fastmcp  # resolve while request is alive\n    asyncio.create_task(later(srv))","handlingStrategy":"try-catch","validationCode":"srv = ctx._fastmcp() if callable(getattr(ctx, \"_fastmcp\", None)) else None\n# only proceed if srv is not None","typeGuard":"def fastmcp_available(ctx) -> bool:\n    try:\n        return ctx._fastmcp() is not None\n    except Exception:\n        return False","tryCatchPattern":"try:\n    server = ctx.fastmcp\nexcept RuntimeError:\n    server = get_server_from_registry()  # fallback lookup","preventionTips":["Never store Context objects beyond the request that produced them.","Resolve ctx.fastmcp (and other request-scoped data) at the start of the handler, not in deferred tasks.","Pass explicit server references to background work instead of the Context."],"tags":["python","context","lifecycle","runtimeerror"],"backgroundTag":"stale-context-reference","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}