tiangolo/fastapi · error · FastAPIError

Prefix and path cannot be both empty (path operation: {name}

Error message

Prefix and path cannot be both empty (path operation: {name})

What it means

Inside `APIRouter.include_router` (routing.py:3281-3295), when no `prefix` is given FastAPI iterates the included router's routes; if any route has a `path` attribute equal to the empty string (`not path`), it raises `FastAPIError`. An empty prefix plus an empty path would resolve to an empty/invalid URL, so FastAPI refuses the include at registration time.

Source

Thrown at fastapi/routing.py:3293

        )
        if prefix:
            assert prefix.startswith("/"), "A path prefix must start with '/'"
            assert not prefix.endswith("/"), (
                "A path prefix must not end with '/', as the routes will start with '/'"
            )
        else:
            for route, route_context in _iter_routes_with_context(router.routes):
                if route_context is None:
                    path = getattr(route, "path", None)
                    name = getattr(route, "name", "unknown")
                elif route_context.starlette_route is not None:
                    path = getattr(route_context.starlette_route, "path", None)
                    name = getattr(route_context.starlette_route, "name", "unknown")
                else:
                    path = route_context.path
                    name = route_context.name
                if path is not None and not path:
                    raise FastAPIError(
                        f"Prefix and path cannot be both empty (path operation: {name})"
                    )
        include_context = _RouterIncludeContext.for_include(
            parent_router=self,
            included_router=router,
            prefix=prefix,
            tags=tags,
            dependencies=dependencies,
            default_response_class=default_response_class,
            responses=responses,
            callbacks=callbacks,
            deprecated=deprecated,
            include_in_schema=include_in_schema,
            generate_unique_id_function=generate_unique_id_function,
        )
        self.routes.append(
            _IncludedRouter(original_router=router, include_context=include_context)
        )

View on GitHub (pinned to 42a41db11f)

Solutions

  1. Give the path operation a real path, e.g. `@router.get("/")` instead of `@router.get("")`.
  2. Provide a `prefix` when including: `app.include_router(router, prefix="/api")`.
  3. Validate generated path strings are non-empty before using them in a decorator.

Example fix

# before
@router.get("")
def root(): ...
app.include_router(router)  # no prefix -> FastAPIError

# after
@router.get("/")
def root(): ...
app.include_router(router)
Defensive patterns

Strategy: validation

Validate before calling

def validate_route_paths(router, prefix: str = "") -> None:
    if not prefix:
        for route in router.routes:
            path = getattr(route, "path", None)
            if path is not None and not path:
                name = getattr(route, "name", "unknown")
                raise ValueError(
                    f"Route {name!r} has empty path; include with a prefix or set path='/'."
                )

# usage, before include:
validate_route_paths(sub_router)
app.include_router(sub_router)  # safe

Type guard

def all_routes_have_path_when_no_prefix(router, prefix: str) -> bool:
    if prefix:
        return True
    return all(
        getattr(r, "path", None) not in ("", None) for r in getattr(router, "routes", [])
    )

Prevention

When it happens

Trigger: Registering a path operation with an empty path — `@router.get("")` — on a sub-router, then `app.include_router(router)` without a `prefix`. Also via a frontend or nested route whose effective path collapses to `""` when no prefix is supplied.

Common situations: Defining a router whose root handler uses `""` expecting the include prefix to fill it in, but forgetting the prefix; refactoring routes and dropping the leading `/`; dynamically generating `path` from a variable that can be empty.

Related errors


AI-assisted analysis of tiangolo/fastapi@42a41db11f (2026-08-04). Data as JSON: /data/errors/9ed5c86d5157d5e2.json. Report an issue: GitHub.