PrefectHQ/fastmcp · error · ValueError
Invalid OpenAPI specification: {e}
Error message
Invalid OpenAPI specification: {e} What it means
OpenAPIProvider.__init__ builds an openapi-core SchemaPath spec and RequestDirector from the supplied spec dict; if that library rejects the document, the exception is logged and re-raised as ValueError('Invalid OpenAPI specification: ...').
Source
Thrown at fastmcp_slim/fastmcp/server/providers/openapi/provider.py:149
self._used_names: dict[str, Counter[str]] = {
"tool": Counter(),
"resource": Counter(),
"resource_template": Counter(),
"prompt": Counter(),
}
# Pre-created component storage
self._tools: dict[str, OpenAPITool] = {}
self._resources: dict[str, OpenAPIResource] = {}
self._templates: dict[str, OpenAPIResourceTemplate] = {}
# Create openapi-core Spec and RequestDirector
try:
self._spec = SchemaPath.from_dict(cast(Any, openapi_spec))
self._director = RequestDirector(self._spec)
except Exception as e:
logger.exception("Failed to initialize RequestDirector")
raise ValueError(f"Invalid OpenAPI specification: {e}") from e
http_routes = parse_openapi_to_http_routes(openapi_spec)
# Process routes
route_maps = (route_maps or []) + DEFAULT_ROUTE_MAPPINGS
for route in http_routes:
route_map = _determine_route_type(route, route_maps)
route_type = route_map.mcp_type
if route_map_fn is not None:
try:
result = route_map_fn(route, route_type)
if result is not None:
route_type = result
logger.debug(
f"Route {route.method} {route.path} mapping customized: "
f"type={route_type.name}"
)View on GitHub (pinned to 1f02114297)
Solutions
- Validate the spec with a linter (e.g. openapi-spec-validator or Swagger Editor)
- Ensure spec['openapi'] is 3.x and 'paths' exists
- Load the file correctly (yaml.safe_load / json.load) and pass the parsed dict
- Read the chained message to find the offending schema path
Example fix
// before
spec = {'swagger': '2.0', 'paths': {}}
provider = FastMCPProvider(spec)
// after
spec = {'openapi': '3.1.0', 'info': {'title': 'api', 'version': '1.0'}, 'paths': {...}}
provider = FastMCPProvider(spec) Defensive patterns
Strategy: validation
Validate before calling
from openapi_spec_validator import validate
def assert_valid_spec(spec: dict) -> None:
validate(spec)
assert isinstance(spec, dict) and 'paths' in spec Type guard
def is_valid_spec(spec: object) -> bool:
return (
isinstance(spec, dict)
and isinstance(spec.get('openapi'), str)
and spec['openapi'].startswith('3.')
and isinstance(spec.get('paths'), dict)
) Try / catch
try:
provider = FastMCPProvider(spec)
except ValueError as e:
if str(e).startswith('Invalid OpenAPI specification'):
log.error('spec rejected: %s', e.__cause__)
raise
raise Prevention
- Run openapi-spec-validator on the document before loading
- Convert Swagger 2.0 specs to OpenAPI 3.x first
- Validate specs in CI to catch schema regressions
When it happens
Trigger: Passing a dict to OpenAPIProvider/FastMCPProvider that is not a valid OpenAPI document (openapi-core validation fails): wrong version field, missing paths, malformed schema objects.
Common situations: Passing a Swagger 2.0 doc instead of OpenAPI 3.x, YAML loaded into the wrong structure, truncated JSON, hand-edited specs with schema typos.
Related errors
- mode must be 'legacy', 'auto', or one of {list(MODERN_PROTOC
- a custom cache store requires CacheConfig.target_id for Fast
- ClientGroup requires at least one client
- Protocol mode for server {name!r} must be a string
- Missing required configuration metadata: {attr}
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/a829163fbb606a93.
Report an issue: GitHub.