{"record":{"id":"0cf3b2d2cfecde2b","repo":"PrefectHQ/fastmcp","slug":"authorization-failed-for-prompt-prompt-name-m","errorCode":null,"errorMessage":"Authorization failed for prompt '{prompt_name}': missing context","messagePattern":"Authorization failed for prompt '(.+?)': missing context","errorType":"exception","errorClass":"AuthorizationError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/middleware/authorization.py","lineNumber":420,"sourceCode":"        context: MiddlewareContext[mt.GetPromptRequestParams],\n        call_next: CallNext[mt.GetPromptRequestParams, PromptResult],\n    ) -> PromptResult:\n        \"\"\"Check auth before prompt render.\"\"\"\n        # STDIO has no auth concept, skip enforcement\n        from fastmcp.server.context import _current_transport\n\n        if _current_transport.get() == \"stdio\":\n            return await call_next(context)\n\n        # Get the prompt being rendered\n        prompt_name = context.message.name\n        fastmcp = context.fastmcp_context\n        if fastmcp is None:\n            logger.warning(\n                f\"AuthMiddleware: fastmcp_context is None for prompt '{prompt_name}'. \"\n                \"Denying access for security.\"\n            )\n            raise AuthorizationError(\n                f\"Authorization failed for prompt '{prompt_name}': missing context\"\n            )\n\n        # get_prompt returns None both when the prompt does not exist and when\n        # component-level auth denied access, so the two cases are\n        # indistinguishable here. Keep the message ambiguous to avoid\n        # disclosing existence of prompts the caller is not authorized to see.\n        version = _requested_version(context.message.meta)\n        prompt = await fastmcp.fastmcp.get_prompt(prompt_name, version=version)\n        if prompt is None:\n            raise AuthorizationError(\n                f\"Authorization failed for prompt '{prompt_name}': \"\n                \"not found or not authorized\"\n            )\n\n        # Global auth check\n        token = get_access_token()\n        ctx = AuthContext(token=token, component=prompt)","sourceCodeStart":402,"sourceCodeEnd":438,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/middleware/authorization.py#L402-L438","documentation":"AuthMiddleware.on_get_prompt fails closed when `context.fastmcp_context` is None for a prompts/get request: authorization cannot be evaluated without the request-scoped FastMCP Context, so it denies access with an AuthorizationError. Reaching this state indicates the request bypassed the dispatch paths that establish a Context.","triggerScenarios":"prompts/get on a non-stdio transport with a MiddlewareContext lacking fastmcp_context — direct middleware calls in tests, custom transports/handlers that skip `Context` setup, or middleware wrapping that loses the request context.","commonSituations":"Unit tests constructing MiddlewareContext by hand; custom ASGI/transport integration that predates or bypasses FastMCP's context establishment; upgrades where custom glue no longer matches FastMCP internals.","solutions":["Invoke prompt rendering through the standard client -> server dispatch so the Context is established automatically.","In tests, run inside `async with Context(fastmcp=mcp, session=...)` and supply that as fastmcp_context to MiddlewareContext.","Update custom transport code to establish a FastMCP Context per request like the built-in transports.","Verify the transport detection (_current_transport) matches the actual transport in use."],"exampleFix":"# before (test)\nctx = MiddlewareContext(message=GetPromptRequestParams(name='greet'), fastmcp_context=None)\nawait mw.on_get_prompt(ctx, call_next)  # AuthorizationError: missing context\n# after\nasync with Context(fastmcp=mcp, session=session) as fctx:\n    ctx = MiddlewareContext(message=GetPromptRequestParams(name='greet'), fastmcp_context=fctx)\n    await mw.on_get_prompt(ctx, call_next)","handlingStrategy":"try-catch","validationCode":"async with Context(fastmcp=mcp, session=session) as fctx:\n    assert fctx is not None, 'prompts/get middleware requires a FastMCP context'","typeGuard":null,"tryCatchPattern":"from fastmcp.exceptions import AuthorizationError\ntry:\n    prompt = await client.get_prompt('greet', {'name': 'world'})\nexcept AuthorizationError as e:\n    if 'missing context' in str(e):\n        logger.error('prompts/get reached auth middleware without context; fix dispatch path')\n    else:\n        raise","preventionTips":["Route prompts/get through the standard client/server dispatch only.","Use Context(fastmcp=..., session=...) in tests that exercise middleware directly.","Keep custom transports aligned with FastMCP's per-request context establishment.","Treat 'fastmcp_context is None' warnings as infrastructure bugs to fix immediately."],"tags":["auth","prompts","middleware","fail-closed"],"backgroundTag":"authorization-failed","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}