PrefectHQ/fastmcp · error · RuntimeError
No active context found. This can happen if: - Called outs
Error message
No active context found. This can happen if: - Called outside an MCP request handler - Called in a background task before the context was established Check `context.request_context` for None before accessing.
What it means
FastMCP exposes a Context dependency that resolves the active per-request MCP context from a contextvar; in background tasks it first consults a snapshot factory (_background_context_factory) captured when the task was spawned. If neither a live request context nor a captured background context exists, entering the context manager raises this RuntimeError. The library throws it because there is genuinely no MCP request in flight, so request-scoped data (session, request_context) cannot be provided.
Source
Thrown at fastmcp_slim/fastmcp/server/dependencies.py:907
async def __aenter__(self) -> Context:
from fastmcp.server.context import _current_context
# Try foreground context first (normal MCP request)
context = _current_context.get()
if context is not None:
return context
# In a background-task worker there is no foreground context; the tasks
# extension installs a factory that builds and enters a worker Context
# from the restored task snapshot. Core has no task engine of its own,
# so this is None unless the extension is active.
factory = _background_context_factory
if factory is not None:
background = await factory()
if background is not None:
return background
raise RuntimeError(
"No active context found. This can happen if:\n"
" - Called outside an MCP request handler\n"
" - Called in a background task before the context was established\n"
"Check `context.request_context` for None before accessing."
)
async def __aexit__(
self,
exc_type: type[BaseException] | None,
exc_value: BaseException | None,
traceback: TracebackType | None,
) -> None:
from fastmcp.server.context import _current_context
ctx = _current_context.get()
if ctx is not None and ctx.is_background_task:
await ctx.__aexit__(exc_type, exc_value, traceback)
View on GitHub (pinned to 1f02114297)
Solutions
- Only access Context inside code executed as part of an MCP request (tool/resource/prompt handler invoked via a client)
- If you must run background work, capture the context snapshot before spawning (FastMCP's background context factory) or pass needed data explicitly as arguments
- Guard with `if ctx.request_context is not None` where the API allows, or check availability before entering
- In tests, use fastmcp's in-memory Client fixture so handlers run inside a real request context
Example fix
// before
async def cleanup():
with Context() as ctx:
await ctx.info("done")
// after
async def my_tool(ctx: Context) -> str:
await ctx.info("done") # ctx provided by the request
return "ok" Defensive patterns
Strategy: type-guard
Validate before calling
from fastmcp.server.dependencies import get_http_request, _current_request # availability probe in_request = _current_request.get() is not None
Type guard
def has_active_context() -> bool:
from fastmcp.server import dependencies
ctx = dependencies._current_context.get(None)
return ctx is not None or dependencies._background_context_factory is not None Try / catch
try:
async with Context() as ctx:
await ctx.info("working")
except RuntimeError as e:
if "No active context" in str(e):
logger.warning("context unavailable; skipping request-scoped logging") Prevention
- Never construct Context outside request handlers; take it as an injected parameter
- For background tasks, capture the context snapshot before spawning the task
- Guard optional context use with `ctx.request_context is not None`
- In tests, always run handlers through a fastmcp Client fixture
When it happens
Trigger: Calling `with Context() as ctx:` (async) from code running outside an MCP request handler — e.g. in a plain asyncio task, at module import, in tests, or in a background worker spawned without capturing the context.
Common situations: Scheduling asyncio.create_task from a tool without the context snapshot mechanism; unit tests calling tool functions directly instead of through a client; logging/telemetry code that touches ctx after the request ended.
Related errors
- Progress dependency requires a FastMCP server context.
- mcp_tool() got unexpected keyword argument(s): {sorted(unkno
- mcp_resource() got unexpected keyword argument(s): {sorted(u
- mcp_prompt() got unexpected keyword argument(s): {sorted(unk
- {name!r} moved to the fastmcp-tasks package. Install it with
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/612401d2efc3446e.
Report an issue: GitHub.