PrefectHQ/fastmcp · error · RuntimeError

No active HTTP request found.

Error message

No active HTTP request found.

What it means

get_http_request() returns the Starlette Request for the current call, first from the MCP SDK request context and then from FastMCP's _current_http_request contextvar. This RuntimeError is thrown when neither is populated — the code is running where no HTTP request is in scope (e.g. stdio transport, background workers, or before initialization middleware completes).

Source

Thrown at fastmcp_slim/fastmcp/server/dependencies.py:537

def get_http_request() -> Request:
    """Get the current HTTP request.

    Tries MCP SDK's request_ctx first, then falls back to FastMCP's HTTP context.
    """
    # Try FastMCP's request context first (set during normal MCP request handling)
    request = None
    fastmcp_ctx = fastmcp_request_ctx.get()
    if fastmcp_ctx is not None:
        request = fastmcp_ctx.request

    # Fallback to FastMCP's HTTP context variable
    # This is needed during `on_initialize` middleware where request_ctx isn't set yet
    if request is None:
        request = _current_http_request.get()

    if request is None:
        raise RuntimeError("No active HTTP request found.")
    return request


def get_http_headers(
    include_all: bool = False,
    include: set[str] | None = None,
) -> dict[str, str]:
    """Extract headers from the current HTTP request if available.

    Never raises an exception, even if there is no active HTTP request (in which case
    an empty dict is returned).

    By default, strips problematic headers like `content-length`, and credential
    headers like `authorization` and `cookie`, that cause issues if forwarded to
    downstream services. If `include_all` is True, all headers are returned.

    The `include` parameter allows specific headers to be included even if they would
    normally be excluded. This is useful for proxy transports that need to forward

View on GitHub (pinned to 1f02114297)

Solutions

  1. Guard with try/except RuntimeError and use a fallback when no HTTP request exists (the library itself does this pattern).
  2. Only use HTTP-dependent helpers (headers, access token) in code paths reachable exclusively over HTTP transport.
  3. For background tasks, capture the needed request data up front instead of re-resolving the request inside the task.

Example fix

// before
headers = get_http_headers()
// after
try:
    headers = get_http_headers()
except RuntimeError:
    headers = {}  # non-HTTP transport (e.g. stdio)
Defensive patterns

Strategy: fallback

Try / catch

try:
    request = get_http_request()
except RuntimeError:
    request = None  # stdio or background context; use defaults
headers = dict(request.headers) if request else {}

Prevention

When it happens

Trigger: Calling get_http_request() (directly or via get_http_headers/get_access_token) under stdio transport; in background task workers without HTTP context propagation; in on_initialize middleware before request_ctx is set; in non-HTTP tests.

Common situations: The same server run over both stdio and HTTP, with code that unconditionally reads HTTP headers; tasks scheduled with asyncio.create_task losing the contextvar; unit tests exercising tools without an HTTP transport.

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/a834d362194626e5. Report an issue: GitHub.