tiangolo/fastapi · error · RuntimeError

Frontend directory ' ' does not exist. Resolved absolute…

Error message

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

What it means

Raised by `_FrontendStaticFiles.__init__` (fastapi/routing.py:1909) as a RuntimeError when `check_dir` is True and `os.path.isdir(directory)` is False. FastAPI verifies the frontend build directory exists at app-construction time so deployment failures surface immediately rather than as 404s in production. The resolved absolute path is included to make path issues (cwd-relative paths, symlinks) easy to diagnose.

Solutions

  1. Run the frontend build first (e.g. `npm run build`) so the directory exists, then start the server.
  2. Use an absolute path: `router.frontend('/', directory=str(Path(__file__).parent.parent / 'dist'))`.
  3. Verify the path at startup: `Path(directory).resolve().is_dir()` and print it before `frontend(...)`.
  4. During local dev, rely on `fastapi dev` (sets FASTAPI_ENV=development) which downgrades this to a warning via check_dir='auto'.

Example fix

// before
router.frontend('/', directory='dist')  # dist does not exist yet
// after
import subprocess, pathlib
subprocess.check_call(['npm', 'run', 'build'])
router.frontend('/', directory=str(pathlib.Path('dist').resolve()))
Defensive patterns

Strategy: validation

Validate before calling

import os, pathlib

directory = pathlib.Path('dist').resolve()
if not directory.is_dir():
    raise FileNotFoundError(f'Frontend directory not found: {directory}')
router.frontend('/', directory=str(directory))

Type guard

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

Try / catch

try:
    router.frontend('/', directory='dist')
except RuntimeError as exc:
    if 'does not exist' in str(exc):
        # build or fix the path, then retry/exit with a clear message
        raise SystemExit(f'Build the frontend first: {exc}')
    raise

Prevention

When it happens

Trigger: Calling `router.frontend('/', directory='dist')` when 'dist' does not exist relative to the process working directory. Deploying before running the frontend build step (`npm run build`) that outputs to 'dist'. Pointing `directory` at a path that is only present in another container/stage. `check_dir` defaults to 'auto' which becomes True unless `FASTAPI_ENV=development`.

Common situations: Running `uvicorn app.main:app` before `npm run build`. Working-directory mismatch: the app is launched from a different folder than where 'dist' lives. Docker multi-stage build that did not copy the build output into the final image. A typo in the directory name.

Related errors


AI-assisted analysis of tiangolo/fastapi@3e8d1526d8 (2026-08-11). Data as JSON: /api/errors/86e6697915ea9fe5. Report an issue: GitHub.

Appendix: 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 3e8d1526d8)