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
- Read the chained exception (raise ... from exc) to see the underlying httpx error
- Verify the server URL/host/port in the OpenAPI spec's servers entry
- Test connectivity with curl or httpx from the same host
- 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
- Health-check the upstream URL at startup
- Pin the servers URL to a verified host
- Install correct CA certificates for TLS endpoints
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
- HTTP error {response.status_code}: {response.reason_phrase}
- HTTP request timed out ({type(exc).__name__})
- Unexpected authorization response: {response.status_code}
- str(e)
- OIDC discovery for issuer {issuer!r} failed: {e}
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/d60e19781ed7ab8d.
Report an issue: GitHub.