{"record":{"id":"3cdab772414d8f40","repo":"tiangolo/fastapi","slug":"frontend-fallback-file-fallback-does-not-exist","errorCode":null,"errorMessage":"Frontend fallback file '{fallback}' does not exist in directory '{directory}'. Resolved absolute directory: '{resolved_absolute_directory}'","messagePattern":"Frontend fallback file '(.+?)' does not exist in directory '(.+?)'\\. Resolved absolute directory: '(.+?)'","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"fastapi/routing.py","lineNumber":1925,"sourceCode":"        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: \"\n                f\"'{self._get_resolved_directory()}'\"\n            )\n\n    def _get_resolved_directory(self) -> str:\n        assert self.directory is not None\n        return _get_resolved_absolute_path(self.directory)\n\n    def get_path(self, scope: Scope) -> str:\n        path = _get_fastapi_scope(scope).get(_FASTAPI_FRONTEND_PATH_KEY, \"\")\n        assert isinstance(path, str)\n        return os.path.normpath(os.path.join(*path.split(\"/\")))\n\n    async def get_response_for_scope(self, scope: Scope) -> Response:\n        if not self.config_checked:\n            await self.check_config()\n            self.config_checked = True","sourceCodeStart":1907,"sourceCodeEnd":1943,"githubUrl":"https://github.com/tiangolo/fastapi/blob/3e8d1526d83a90aaf7d6eb6dc682bf150f180b25/fastapi/routing.py#L1907-L1943","documentation":"Raised by `_FrontendStaticFiles._check_fallback_file` (fastapi/routing.py:1925) at app-construction time when `check_dir` is True and the fallback file ('index.html' or '404.html') does not exist inside the frontend directory or is not a regular file. FastAPI guarantees the configured fallback exists at startup so SPA/404 behavior cannot silently break later. The resolved absolute directory is included for diagnostics.","triggerScenarios":"Calling `router.frontend('/', directory='dist', fallback='index.html')` when 'dist' lacks 'index.html'. Setting `fallback='404.html'` without providing a 404.html in the build output. The fallback file exists but is a directory or symlink to a non-file.","commonSituations":"Frontend build outputs to a different filename (e.g. '200.html' for some SPA tools) instead of 'index.html'. Partial/corrupted build that emitted assets but not the entry HTML. Misconfigured `fallback` value chosen by copying from another project that used a different build setup.","solutions":["Ensure the build emits the chosen fallback file in the directory (add an index.html / 404.html).","Switch to `fallback='auto'` which does not require a specific file at startup.","Set `fallback=None` if you do not want SPA/404 fallback behavior.","Point `directory` at the correct build output folder containing the HTML."],"exampleFix":"// before\nrouter.frontend('/', directory='dist', fallback='404.html')  # no 404.html\n// after\nrouter.frontend('/', directory='dist', fallback='auto')","handlingStrategy":"validation","validationCode":"import os, pathlib\n\ndef ensure_fallback(directory: str, fallback: str) -> None:\n    p = pathlib.Path(directory) / fallback\n    if not (p.is_file()):\n        raise FileNotFoundError(f'Missing fallback file: {p}')\n\nensure_fallback('dist', 'index.html')\nrouter.frontend('/', directory='dist', fallback='index.html')","typeGuard":"def fallback_file_ok(directory: object, fallback: str) -> bool:\n    import os, pathlib\n    if not isinstance(directory, (str, os.PathLike)):\n        return False\n    return (pathlib.Path(directory) / fallback).is_file()","tryCatchPattern":null,"preventionTips":["Prefer fallback='auto' unless you require a specific file.","Verify the fallback file is emitted by your build config.","Add a CI check that asserts index.html/404.html exists in the build output."],"tags":["fastapi","frontend-routing","filesystem","configuration"],"backgroundTag":null,"analyzedSha":"3e8d1526d83a90aaf7d6eb6dc682bf150f180b25","analyzedAt":"2026-08-11T02:34:52.986Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}