PrefectHQ/fastmcp · error · RuntimeError
request_id is not available because the MCP session has not
Error message
request_id is not available because the MCP session has not been established yet. Check `context.request_context` for None before accessing this attribute.
What it means
Context.request_id returns the unique MCP request ID from the request_context. When the MCP session has not been established (request_context is None — e.g. the Context is not attached to an in-flight request), there is no request ID to report, so a RuntimeError is raised and the message tells you to check request_context for None first.
Source
Thrown at fastmcp_slim/fastmcp/server/context.py:702
return False
return client_supports_extension(session, extension_id)
@property
def client_id(self) -> str | None:
"""Get the client ID if available."""
rc = self.request_context
return (
rc.meta.get("client_id") if rc is not None and rc.meta is not None else None
)
@property
def request_id(self) -> str:
"""Get the unique ID for this request.
Raises RuntimeError if MCP request context is not available.
"""
if self.request_context is None:
raise RuntimeError(
"request_id is not available because the MCP session has not been established yet. "
"Check `context.request_context` for None before accessing this attribute."
)
return str(self.request_context.request_id)
@property
def session_id(self) -> str:
"""Get the MCP session ID for ALL transports.
Returns the session ID that can be used as a key for session-based
data storage (e.g., Redis) to share data between tool calls within
the same client session.
Returns:
The session ID for StreamableHTTP transports, or a generated ID
for other transports.
Raises:View on GitHub (pinned to 1f02114297)
Solutions
- Gate access on the context: only read ctx.request_id when ctx.request_context is not None.
- Move code that needs request_id into the request path (tool/resource/prompt execution, request-scoped middleware).
- Use a fallback identifier (e.g. generated uuid) when request_context is None.
- In background tasks, capture request_id before spawning the task.
Example fix
// before
async def tool(x: int, ctx: Context):
log.info("rid=%s", ctx.request_id) # may raise
// after
async def tool(x: int, ctx: Context):
rid = ctx.request_id if ctx.request_context is not None else "no-request"
log.info("rid=%s", rid) Defensive patterns
Strategy: type-guard
Validate before calling
rid = str(ctx.request_context.request_id) if ctx.request_context is not None else None
Type guard
def has_request_context(ctx) -> bool:
return ctx.request_context is not None Try / catch
try:
rid = ctx.request_id
except RuntimeError:
rid = str(uuid.uuid4()) # no active request Prevention
- Only read request-scoped properties inside tool/resource/prompt handlers or request middleware.
- Check ctx.request_context for None before any request_id/session access.
- Capture request-scoped values before spawning background tasks.
When it happens
Trigger: Accessing ctx.request_id inside code that runs outside a request lifecycle: at import/setup time, inside on_initialize before the first request, in background tasks, or in tests that build a Context manually.
Common situations: Logging middleware hooks that fire before a request exists; startup code calling request_id to correlate logs; unit tests exercising tools without a client session.
Related errors
- session is not available because the MCP session has not bee
- FastMCP instance is no longer available
- Unexpected CreateTaskResult: Context calls should not have t
- session_id is not available because no session exists. This
- No access token available. Cannot perform OBO exchange.
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/4f42bb10547f09fa.
Report an issue: GitHub.