Use this guide to diagnose common azure-functions-openapi issues in local development and CI.
/api/docsreturns 404- page loads but no operations appear
- browser console shows CSP or fetch errors
- Confirm docs route exists:
@app.route(route="docs", methods=["GET"], auth_level=func.AuthLevel.ANONYMOUS)
def docs(req: func.HttpRequest) -> func.HttpResponse:
return render_swagger_ui(openapi_url="/api/openapi.json")- Confirm OpenAPI route is reachable:
curl "http://localhost:7071/api/openapi.json"- Confirm
openapi_urlinrender_swagger_ui(...)matches your route.
- set explicit
openapi_url="/api/openapi.json" - keep docs and spec routes under same host/origin
- if CSP blocks assets in your environment, pass an explicit
custom_csp
pathsis empty- only some operations are present
- handler missing
@openapi - module containing handlers not imported at startup
- decorator registration failed due to invalid parameter value
Inspect registry during runtime:
from azure_functions_openapi.decorator import get_openapi_registry
print(get_openapi_registry().keys())Registry keys are keyed by the decorated function's short name. When two
handlers share the same short name, the earlier (displaced) entry is preserved
under its fully-qualified id (module.qualname) in addition to the short-name
key, so no registration is silently lost. If you rely on these keys for
debugging, expect both a short-name key and a fully-qualified key when name
collisions occur.
- add
@openapito every operation you want documented - ensure all function modules are imported before generating specs
- correct invalid decorator values (for example invalid route path)
- schema conversion errors
- model APIs differ (
schema()vsmodel_json_schema())
azure-functions-openapi requires Pydantic v2. If you are using Pydantic v1, upgrade to v2 before using this library.
- passing a dict to
request_modelorresponse_model - mixing incompatible Pydantic usage patterns in your own function code
- pass Pydantic classes to
request_modelandresponse_model - if you need raw schema dicts, use
request_bodyandresponse - keep a single Pydantic major version in your environment
- function route works but docs path is different
- path parameters not matching runtime route
@app.route(route=...) controls runtime routing.
@openapi(route=...) controls documented path.
If they diverge, behavior and docs diverge.
Keep them aligned by design:
@openapi(route="/api/users/{user_id}", method="get")
@app.route(route="users/{user_id}", methods=["GET"])!!! tip
Documented routes often include /api/... while app.route may be relative. Be consistent across your app and docs conventions.
ValueError: Invalid route path ...ValueError: Invalid operation ID ...
- use safe route characters (
a-z,A-Z, digits,_,-,/,{}, no spaces) - avoid dangerous patterns (
..,javascript:, script snippets) - use readable operation IDs (letters, digits, underscore)
- generated spec has no routes
- wrong output format/version
- use explicit flags:
--format,--openapi-version - confirm decorated modules are imported in process where CLI runs
azure-functions-openapi generate --format json --openapi-version 3.1 --output openapi.json- operation visible but execution fails in browser
- CORS/network/auth errors
- verify API host and route are reachable from browser
- verify request headers expected by your function
- verify auth requirements if endpoint is not anonymous
Use this checklist in order:
- Confirm
@openapidecorators exist on expected handlers - Confirm
openapi.jsonendpoint returns valid JSON - Confirm
docsendpoint callsrender_swagger_ui(openapi_url="/api/openapi.json") - Confirm registry has expected function keys
- Confirm route/method consistency between Azure route and OpenAPI metadata