tiangolo/fastapi · error · RuntimeError

Frontend directory '{directory}' does not exist. Resolved ab

Error message

Frontend directory '{directory}' does not exist. Resolved absolute path: '{resolved_absolute_path}'

What it means

`_FrontendStaticFiles.__init__` (routing.py:1908-1912) raises `RuntimeError` when `check_dir` is true and `os.path.isdir(directory)` is false. `check_dir` is resolved by `_resolve_frontend_check_dir` (routing.py:1881-1896): it is `True` unless `check_dir="auto"` AND `FASTAPI_ENV == "development"`. So in normal/prod runs a missing frontend directory aborts app startup; under `fastapi dev` (FASTAPI_ENV=development) it is only a warning.

Source

Thrown at fastapi/routing.py:1909

        warnings.warn(
            f"Frontend directory '{directory}' does not exist. "
            f"Resolved absolute path: '{_get_resolved_absolute_path(directory)}'",
            stacklevel=3,
        )
    return False


class _FrontendStaticFiles(StaticFiles):
    def __init__(
        self,
        *,
        directory: str | os.PathLike[str],
        fallback: Literal["auto", "index.html", "404.html"] | None,
        check_dir: bool,
    ) -> None:
        self.fallback = fallback
        if check_dir and not os.path.isdir(directory):
            raise RuntimeError(
                f"Frontend directory '{directory}' does not exist. "
                f"Resolved absolute path: '{_get_resolved_absolute_path(directory)}'"
            )
        super().__init__(
            directory=directory,
            html=True,
            check_dir=check_dir,
            follow_symlink=False,
        )
        if check_dir and fallback in {"index.html", "404.html"}:
            self._check_fallback_file(fallback)

    def _check_fallback_file(self, fallback: str) -> None:
        _, stat_result = self.lookup_path(fallback)
        if stat_result is None or not stat.S_ISREG(stat_result.st_mode):
            raise RuntimeError(
                f"Frontend fallback file '{fallback}' does not exist in "
                f"directory '{self.directory}'. Resolved absolute directory: "

View on GitHub (pinned to 42a41db11f)

Solutions

  1. Build the frontend before starting the app so the directory exists.
  2. Pass an absolute path resolved from the project root, e.g. `Path(__file__).resolve().parent.parent / "dist"`.
  3. During local dev use `fastapi dev` (sets FASTAPI_ENV=development) or set `FASTAPI_ENV=development` to downgrade the failure to a warning.
  4. Set `check_dir=False` only if you intentionally create the directory later at runtime.

Example fix

# before
app.frontend("/", directory="dist")  # dist/ missing in prod

# after
from pathlib import Path
DIST = Path(__file__).resolve().parent.parent / "dist"
app.frontend("/", directory=str(DIST))
Defensive patterns

Strategy: validation

Validate before calling

import os
from pathlib import Path

def resolve_frontend_dir(directory: str | os.PathLike[str]) -> str:
    resolved = Path(directory).resolve()
    if not resolved.is_dir():
        raise FileNotFoundError(
            f"Frontend directory '{directory}' missing (resolved: {resolved}). "
            f"Build the frontend first."
        )
    return str(resolved)

# usage
dist = resolve_frontend_dir(os.getenv("FRONTEND_DIR", "dist"))
app.frontend("/", directory=dist)

Type guard

import os

def frontend_dir_exists(directory: object) -> bool:
    return isinstance(directory, (str, os.PathLike)) and os.path.isdir(directory)

Try / catch

# Construction-time failure: catch at app bootstrap to give a clear message.
try:
    app.frontend("/", directory=dist)
except RuntimeError as exc:
    raise SystemExit(f"Startup aborted: {exc}. Run the frontend build first.") from exc

Prevention

When it happens

Trigger: `app.frontend("/", directory="dist")` where `dist/` does not exist on the working directory at startup, run without `FASTAPI_ENV=development`. Same with an absolute path that points nowhere, or a path relative to the wrong cwd.

Common situations: Running `uvicorn app.main:app` before building the frontend (`npm run build`); deploying with a relative `dist` path while the process cwd differs; CI running the app without the build artifact stage; mis-capitalized directory name.

Related errors


AI-assisted analysis of tiangolo/fastapi@42a41db11f (2026-08-04). Data as JSON: /data/errors/86e6697915ea9fe5.json. Report an issue: GitHub.