tiangolo/fastapi · error · AssertionError
A frontend path cannot be empty
Error message
A frontend path cannot be empty
What it means
`_normalize_frontend_path` (routing.py:1853-1860) rejects an empty path with `AssertionError`. It is called by `APIRouter.frontend()` (routing.py:2704) when you register a static frontend mount. The path is the URL prefix under which the built frontend is served, and an empty prefix is ambiguous, so FastAPI aborts at router/app construction time.
Source
Thrown at fastapi/routing.py:1855
yield RouteContext(original_route)
else:
yield RouteContext(original_route, route_context)
def _iter_routes_with_context(
routes: Sequence[BaseRoute],
) -> Iterator[tuple[BaseRoute, _EffectiveRouteContext | None]]:
for route in routes:
if isinstance(route, _IncludedRouter):
for route_context in route.effective_route_contexts():
yield route_context.original_route, route_context
else:
yield route, None
def _normalize_frontend_path(path: str) -> str:
if not path:
raise AssertionError("A frontend path cannot be empty")
if not path.startswith("/"):
raise AssertionError("A frontend path must start with '/'")
if path != "/":
path = path.rstrip("/")
return path
def _join_frontend_paths(prefix: str, path: str) -> str:
if not prefix:
return path
if path == "/":
return prefix
return prefix + path
def _frontend_path_specificity(path: str) -> int:
if path == "/":
return 0View on GitHub (pinned to 42a41db11f)
Solutions
- Pass a non-empty path beginning with `/`, typically `"/"` for a root-mounted SPA.
- If the mount point is configurable, default it to `"/"` and validate before calling `.frontend(...)`.
- Check for empty/None before invoking `.frontend()` and raise a clear config error of your own.
Example fix
# before
app.frontend("", directory="dist")
# after
app.frontend("/", directory="dist") Defensive patterns
Strategy: validation
Validate before calling
def assert_frontend_path(path: str) -> str:
if not isinstance(path, str) or path == "":
raise ValueError("frontend path must be a non-empty string starting with '/'")
if not path.startswith("/"):
path = "/" + path.lstrip("/")
return path
# usage
fp = assert_frontend_path(config.get("FRONTEND_PATH", "/"))
app.frontend(fp, directory="dist") Type guard
def is_valid_frontend_path(path: object) -> bool:
return isinstance(path, str) and len(path) > 0 and path.startswith("/") Prevention
- Default configurable frontend paths to `/` rather than empty string.
- Validate config values once at startup before building the app.
- Keep `.frontend()` calls behind a small helper that normalizes the path.
When it happens
Trigger: Calling `app.frontend("", directory="dist")` or `router.frontend("", directory=...)`. Passing a computed path variable that resolves to `""`.
Common situations: Building the path from config/env that is unset and defaults to empty; copy-pasting an example but forgetting the leading segment; dynamically composing `f"{base}"` where base is empty.
Related errors
- A frontend path must start with '/'
- Frontend directory '{directory}' does not exist. Resolved ab
- Frontend fallback file '{fallback}' does not exist in direct
- fallback must be 'auto', 'index.html', '404.html', or None
- Prefix and path cannot be both empty (path operation: {name}
AI-assisted analysis of tiangolo/fastapi@42a41db11f (2026-08-04).
Data as JSON: /data/errors/89e90dcc5e28695b.json.
Report an issue: GitHub.