PrefectHQ/fastmcp · error · ValueError

Request error ({type(exc).__name__}): {exc!s}

Error message

Request error ({type(exc).__name__}): {exc!s}

What it means

Any non-timeout httpx request error (connection refused, DNS failure, TLS errors, too many redirects) raised while sending an OpenAPI proxied request is re-raised as ValueError('Request error (TypeName): details') by _send_request, preserving the original exception as __cause__.

Source

Thrown at fastmcp_slim/fastmcp/server/providers/openapi/components.py:88

        error_message += f" - {error_data}"
    except (json.JSONDecodeError, ValueError):
        if response.text:
            error_message += f" - {response.text}"
    raise ValueError(error_message)


async def _send_request(
    client: httpx2.AsyncClient,
    request: httpx2.Request,
) -> httpx2.Response:
    """Send a request while preserving transitional legacy-client errors."""
    try:
        return await client.send(request)
    except Exception as exc:
        if is_timeout_error(exc):
            raise ValueError(f"HTTP request timed out ({type(exc).__name__})") from exc
        if is_request_error(exc):
            raise ValueError(f"Request error ({type(exc).__name__}): {exc!s}") from exc
        raise


def _extract_mime_type_from_route(route: HTTPRoute) -> str:
    """Extract the primary MIME type from an HTTPRoute's response definitions.

    Looks for the first successful response (2xx) and returns its content type.
    Prefers JSON-compatible types when multiple are available.
    Falls back to "application/json" when no response content type is declared.
    """
    if not route.responses:
        return _DEFAULT_MIME_TYPE

    # Priority order for success status codes
    success_codes = ["200", "201", "202", "204"]

    response_info = None
    for status_code in success_codes:

View on GitHub (pinned to 1f02114297)

Solutions

  1. Read the chained exception (raise ... from exc) to see the underlying httpx error
  2. Verify the server URL/host/port in the OpenAPI spec's servers entry
  3. Test connectivity with curl or httpx from the same host
  4. Fix TLS (install CA bundle or use verify= appropriately)

Example fix

// before
spec['servers'] = [{'url': 'http://localhost:9999'}]
// after
spec['servers'] = [{'url': 'https://api.example.com'}]
Defensive patterns

Strategy: try-catch

Validate before calling

import httpx
async def can_connect(url: str) -> bool:
    try:
        async with httpx.AsyncClient() as c:
            await c.get(url, timeout=5.0)
        return True
    except httpx.RequestError:
        return False

Try / catch

try:
    result = await component.read()
except ValueError as e:
    if e.__cause__ and not isinstance(e.__cause__, httpx.TimeoutException):
        log.error('upstream unreachable: %s', e.__cause__)
    raise

Prevention

When it happens

Trigger: A tool run or resource read where client.send() raises httpx.ConnectError, httpx.ConnectTimeout (non-timeout class), httpx.ProtocolError, etc.

Common situations: Backend down or wrong port, DNS misconfiguration, self-signed/invalid TLS certificates, proxy misconfig in the environment.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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