{"record":{"id":"86e6697915ea9fe5","repo":"tiangolo/fastapi","slug":"frontend-directory-directory-does-not-exist-r","errorCode":null,"errorMessage":"Frontend directory '{directory}' does not exist. Resolved absolute path: '{resolved_absolute_path}'","messagePattern":"Frontend directory '(.+?)' does not exist\\. Resolved absolute path: '(.+?)'","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"fastapi/routing.py","lineNumber":1909,"sourceCode":"        warnings.warn(\n            f\"Frontend directory '{directory}' does not exist. \"\n            f\"Resolved absolute path: '{_get_resolved_absolute_path(directory)}'\",\n            stacklevel=3,\n        )\n    return False\n\n\nclass _FrontendStaticFiles(StaticFiles):\n    def __init__(\n        self,\n        *,\n        directory: str | os.PathLike[str],\n        fallback: Literal[\"auto\", \"index.html\", \"404.html\"] | None,\n        check_dir: bool,\n    ) -> None:\n        self.fallback = fallback\n        if check_dir and not os.path.isdir(directory):\n            raise RuntimeError(\n                f\"Frontend directory '{directory}' does not exist. \"\n                f\"Resolved absolute path: '{_get_resolved_absolute_path(directory)}'\"\n            )\n        super().__init__(\n            directory=directory,\n            html=True,\n            check_dir=check_dir,\n            follow_symlink=False,\n        )\n        if check_dir and fallback in {\"index.html\", \"404.html\"}:\n            self._check_fallback_file(fallback)\n\n    def _check_fallback_file(self, fallback: str) -> None:\n        _, stat_result = self.lookup_path(fallback)\n        if stat_result is None or not stat.S_ISREG(stat_result.st_mode):\n            raise RuntimeError(\n                f\"Frontend fallback file '{fallback}' does not exist in \"\n                f\"directory '{self.directory}'. Resolved absolute directory: \"","sourceCodeStart":1891,"sourceCodeEnd":1927,"githubUrl":"https://github.com/tiangolo/fastapi/blob/3e8d1526d83a90aaf7d6eb6dc682bf150f180b25/fastapi/routing.py#L1891-L1927","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","solutions":["Run the frontend build first (e.g. `npm run build`) so the directory exists, then start the server.","Use an absolute path: `router.frontend('/', directory=str(Path(__file__).parent.parent / 'dist'))`.","Verify the path at startup: `Path(directory).resolve().is_dir()` and print it before `frontend(...)`.","During local dev, rely on `fastapi dev` (sets FASTAPI_ENV=development) which downgrades this to a warning via check_dir='auto'."],"exampleFix":"// before\nrouter.frontend('/', directory='dist')  # dist does not exist yet\n// after\nimport subprocess, pathlib\nsubprocess.check_call(['npm', 'run', 'build'])\nrouter.frontend('/', directory=str(pathlib.Path('dist').resolve()))","handlingStrategy":"validation","validationCode":"import os, pathlib\n\ndirectory = pathlib.Path('dist').resolve()\nif not directory.is_dir():\n    raise FileNotFoundError(f'Frontend directory not found: {directory}')\nrouter.frontend('/', directory=str(directory))","typeGuard":"def frontend_dir_exists(directory: object) -> bool:\n    import os\n    return isinstance(directory, (str, os.PathLike)) and os.path.isdir(directory)","tryCatchPattern":"try:\n    router.frontend('/', directory='dist')\nexcept RuntimeError as exc:\n    if 'does not exist' in str(exc):\n        # build or fix the path, then retry/exit with a clear message\n        raise SystemExit(f'Build the frontend first: {exc}')\n    raise","preventionTips":["Run the frontend build (npm run build) before starting the server.","Use absolute, resolved paths derived from __file__.","In CI, assert the directory exists in the deploy step before launching uvicorn."],"tags":["fastapi","frontend-routing","filesystem","deployment","configuration"],"backgroundTag":null,"analyzedSha":"3e8d1526d83a90aaf7d6eb6dc682bf150f180b25","analyzedAt":"2026-08-11T02:34:52.986Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}