{"record":{"id":"e3a526c6cc3a4ed1","repo":"tiangolo/fastapi","slug":"fallback-must-be-auto-index-html-404-html","errorCode":null,"errorMessage":"fallback must be 'auto', 'index.html', '404.html', or None","messagePattern":"fallback must be 'auto', 'index\\.html', '404\\.html', or None","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"fastapi/routing.py","lineNumber":2057,"sourceCode":"    for media_type, quality in _iter_accept_media_types(\n        request.headers.get(\"accept\", \"\")\n    ):\n        if media_type in {\"text/html\", \"application/xhtml+xml\"} and quality != 0:\n            return True\n    return False\n\n\nclass _FrontendRoute(BaseRoute):\n    def __init__(\n        self,\n        path: str,\n        *,\n        directory: str | os.PathLike[str],\n        fallback: Literal[\"auto\", \"index.html\", \"404.html\"] | None = \"auto\",\n        check_dir: bool,\n    ) -> None:\n        if fallback not in {\"auto\", \"index.html\", \"404.html\", None}:\n            raise AssertionError(\n                \"fallback must be 'auto', 'index.html', '404.html', or None\"\n            )\n        self.path = _normalize_frontend_path(path)\n        self.methods = {\"GET\", \"HEAD\"}\n        self.app = _FrontendStaticFiles(\n            directory=directory, fallback=fallback, check_dir=check_dir\n        )\n\n    def matches(self, scope: Scope) -> tuple[Match, Scope]:\n        return self.matches_with_path(scope, self.path)\n\n    def matches_with_path(self, scope: Scope, path: str) -> tuple[Match, Scope]:\n        if scope[\"type\"] != \"http\":\n            return Match.NONE, {}\n        frontend_path = self._get_frontend_path(path, get_route_path(scope))\n        if frontend_path is None:\n            return Match.NONE, {}\n        child_scope = {","sourceCodeStart":2039,"sourceCodeEnd":2075,"githubUrl":"https://github.com/tiangolo/fastapi/blob/3e8d1526d83a90aaf7d6eb6dc682bf150f180b25/fastapi/routing.py#L2039-L2075","documentation":"Raised by `_FrontendRoute.__init__` (fastapi/routing.py:2057) as an AssertionError when the `fallback` argument is not one of the allowed values {'auto', 'index.html', '404.html', None}. FastAPI restricts fallback to a fixed literal set so that fallback semantics are well-defined; any other string (e.g. 'main.html', 'true', 0) is rejected at route setup time.","triggerScenarios":"Calling `router.frontend('/', directory='dist', fallback='main.html')`. Passing a boolean or integer instead of the literal (`fallback=True`). Passing a typo like `fallback='Auto'` (capitalized). Passing an arbitrary filename expecting it to be used as fallback.","commonSituations":"Assuming any filename can be a fallback. Copying example code that used a non-standard value. Case-sensitivity mistakes. Passing a value read from config without validating it against the allowed set.","solutions":["Use one of the allowed literals: `fallback='auto'` (default), `'index.html'`, `'404.html'`, or `None`.","If you need a custom file, place it as index.html/404.html in the directory and select the matching literal.","Validate config-driven values against the allowed set before calling `frontend`."],"exampleFix":"// before\nrouter.frontend('/', directory='dist', fallback='main.html')\n// after\nrouter.frontend('/', directory='dist', fallback='index.html')","handlingStrategy":"validation","validationCode":"from typing import Literal\n\nALLOWED = {'auto', 'index.html', '404.html', None}\n\ndef coerce_fallback(value: str | None) -> Literal['auto','index.html','404.html'] | None:\n    if value not in ALLOWED:\n        raise ValueError(f'fallback must be one of {ALLOWED}')\n    return value  # type: ignore[return-value]\n\nrouter.frontend('/', directory='dist', fallback=coerce_fallback(cfg.get('fallback')))","typeGuard":"def is_allowed_fallback(value: object) -> bool:\n    return value in {'auto', 'index.html', '404.html', None}","tryCatchPattern":null,"preventionTips":["Constrain config options to the allowed literal set before passing to frontend().","Use mypy/pyright Literal types to catch invalid fallback values statically.","Avoid passing arbitrary filenames as fallback."],"tags":["fastapi","frontend-routing","configuration","assertion"],"backgroundTag":null,"analyzedSha":"3e8d1526d83a90aaf7d6eb6dc682bf150f180b25","analyzedAt":"2026-08-11T02:34:52.986Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}