fastapi/fastapi
Debugging
Where logs come from
fastapi/logger.py exposes a single module-level logger = logging.getLogger("fastapi"). The framework is sparing with logging — most diagnostics come from raised exceptions rather than log statements.
To turn on FastAPI logs in a debug session:
import logging
logging.getLogger("fastapi").setLevel(logging.DEBUG)For the wider stack you usually also want:
logging.getLogger("uvicorn").setLevel(logging.DEBUG)
logging.getLogger("starlette").setLevel(logging.DEBUG)Common error shapes
RequestValidationError
Raised by the dependency resolver when request data does not match the function signature. Default handler in fastapi/exception_handlers.py:request_validation_exception_handler returns {"detail": [...]} with HTTP 422.
Newer versions (see _extract_endpoint_context in fastapi/routing.py) attach EndpointContext — function name, file, line, registered path — so the validator's error messages name the endpoint, not just the field.
ResponseValidationError
Raised by serialize_response in fastapi/routing.py when a function's return value does not match its declared response_model (or its return type annotation). HTTP 500. The error class is in fastapi/exceptions.py.
FastAPIError
Generic framework error from fastapi/exceptions.py. Two notable subclasses:
DependencyScopeError— raised when afunction-scoped dependency depends on arequest-scoped dependency. SeeDependant.computed_scopeinfastapi/dependencies/models.py.PydanticV1NotSupportedError— raised at model-creation time (fastapi/utils.py:create_model_field).
"Response not awaited"
The message in fastapi/routing.py:request_response is shown when a dependency-with-yield's except clause swallowed a real exception. The error message is verbose because the failure mode is genuinely confusing — a bare except or except Exception inside a yield block can look fine until you wonder why the response never went out.
Debugging request resolution
- Set a breakpoint in
solve_dependencies(fastapi/dependencies/utils.py). - Inspect the
Dependantargument. Its tree should reflect the function signature. - Check the
Dependant.computed_scopefor unexpectedfunctionvsrequestmismatches.
For OpenAPI debugging:
- Call
app.openapi()from a Python REPL or a one-off test. It returns the same dict served at/openapi.json. - The generator entry point is
get_openapi(...)infastapi/openapi/utils.py. Most of the work happens in_get_openapi_operation_parameters,_get_openapi_operation_request_body, and_get_openapi_operation_response.
Reproducing translations / docs failures
The docs build is opinionated about MkDocs Material insiders; scripts/docs.py detects whether the material[insiders] package is installed and switches config accordingly. If a docs build only fails on CI, mismatched MkDocs versions are usually the cause. Run python scripts/docs.py build-all locally to reproduce.
Performance regressions
Benchmarks live in tests/benchmarks/ and run on CodSpeed via pytest-codspeed (see .github/workflows/test.yml). When a CodSpeed comment says a function regressed, the framework's hot path is one of:
solve_dependencies(fastapi/dependencies/utils.py).serialize_response(fastapi/routing.py).- Pydantic field validation (out of FastAPI's hands — usually a Pydantic upgrade).
jsonable_encoder(fastapi/encoders.py).
A common refactor mistake: adding inspect.iscoroutinefunction calls inside the hot path is expensive; cache them on Dependant (it already has is_coroutine_callable, is_async_gen_callable, is_gen_callable as @cached_property).
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.
Previous
Testing
Next
Patterns and conventions