Factory.ai

Open-Source Wikis

/

FastAPI

/

How to contribute

/

Debugging

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 a function-scoped dependency depends on a request-scoped dependency. See Dependant.computed_scope in fastapi/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

  1. Set a breakpoint in solve_dependencies (fastapi/dependencies/utils.py).
  2. Inspect the Dependant argument. Its tree should reflect the function signature.
  3. Check the Dependant.computed_scope for unexpected function vs request mismatches.

For OpenAPI debugging:

  1. Call app.openapi() from a Python REPL or a one-off test. It returns the same dict served at /openapi.json.
  2. The generator entry point is get_openapi(...) in fastapi/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.

Debugging – FastAPI wiki | Factory