Troubleshooting¶
Use this guide to diagnose common azure-functions-openapi issues in local development and CI.
1) Swagger UI not loading¶
Symptoms¶
/api/docsreturns 404- page loads but no operations appear
- browser console shows CSP or fetch errors
Checks¶
- 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:
- Confirm
openapi_urlinrender_swagger_ui(...)matches your route.
Fixes¶
- 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
2) Spec not showing all endpoints¶
Symptoms¶
pathsis empty- only some operations are present
Root causes¶
- handler missing
@openapi - module containing handlers not imported at startup
- decorator registration failed due to invalid parameter value
Checks¶
Inspect registry during runtime:
from azure_functions_openapi.decorator import get_openapi_registry
print(get_openapi_registry().keys())
Fixes¶
- 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)
3) Pydantic v1 vs v2 issues¶
Symptoms¶
- schema conversion errors
- model APIs differ (
schema()vsmodel_json_schema())
What the library does¶
azure-functions-openapi requires Pydantic v2. If you are using Pydantic v1, upgrade to v2 before using this library.
Common mistakes¶
- passing a dict to
request_modelorresponse_model - mixing incompatible Pydantic usage patterns in your own function code
Fixes¶
- 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
4) Route mismatch between function and OpenAPI output¶
Symptoms¶
- function route works but docs path is different
- path parameters not matching runtime route
Why this happens¶
@app.route(route=...) controls runtime routing.
@openapi(route=...) controls documented path.
If they diverge, behavior and docs diverge.
Fix¶
Keep them aligned by design:
@app.route(route="users/{user_id}", methods=["GET"])
@openapi(route="/api/users/{user_id}", method="get")
Tip
Documented routes often include /api/... while app.route may be relative. Be consistent across your app and docs conventions.
5) Invalid route or operation ID validation errors¶
Symptoms¶
ValueError: Invalid route path ...ValueError: Invalid operation ID ...
Fixes¶
- use safe route characters (
a-z,A-Z, digits,_,-,/,{}, no spaces) - avoid dangerous patterns (
..,javascript:, script snippets) - use readable operation IDs (letters, digits, underscore)
6) CLI generates empty or unexpected output¶
Symptoms¶
- generated spec has no routes
- wrong output format/version
Checks¶
- use explicit flags:
--format,--openapi-version - confirm decorated modules are imported in process where CLI runs
Example¶
7) Swagger UI loads but Try it out fails¶
Symptoms¶
- operation visible but execution fails in browser
- CORS/network/auth errors
Checks¶
- verify API host and route are reachable from browser
- verify request headers expected by your function
- verify auth requirements if endpoint is not anonymous
8) Debug checklist¶
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