{"record":{"id":"9ed5c86d5157d5e2","repo":"tiangolo/fastapi","slug":"prefix-and-path-cannot-be-both-empty-path-operati","errorCode":null,"errorMessage":"Prefix and path cannot be both empty (path operation: {name})","messagePattern":"Prefix and path cannot be both empty \\(path operation: (.+?)\\)","errorType":"exception","errorClass":"FastAPIError","httpStatus":null,"severity":"error","filePath":"fastapi/routing.py","lineNumber":3293,"sourceCode":"        )\n        if prefix:\n            assert prefix.startswith(\"/\"), \"A path prefix must start with '/'\"\n            assert not prefix.endswith(\"/\"), (\n                \"A path prefix must not end with '/', as the routes will start with '/'\"\n            )\n        else:\n            for route, route_context in _iter_routes_with_context(router.routes):\n                if route_context is None:\n                    path = getattr(route, \"path\", None)\n                    name = getattr(route, \"name\", \"unknown\")\n                elif route_context.starlette_route is not None:\n                    path = getattr(route_context.starlette_route, \"path\", None)\n                    name = getattr(route_context.starlette_route, \"name\", \"unknown\")\n                else:\n                    path = route_context.path\n                    name = route_context.name\n                if path is not None and not path:\n                    raise FastAPIError(\n                        f\"Prefix and path cannot be both empty (path operation: {name})\"\n                    )\n        include_context = _RouterIncludeContext.for_include(\n            parent_router=self,\n            included_router=router,\n            prefix=prefix,\n            tags=tags,\n            dependencies=dependencies,\n            default_response_class=default_response_class,\n            responses=responses,\n            callbacks=callbacks,\n            deprecated=deprecated,\n            include_in_schema=include_in_schema,\n            generate_unique_id_function=generate_unique_id_function,\n        )\n        self.routes.append(\n            _IncludedRouter(original_router=router, include_context=include_context)\n        )","sourceCodeStart":3275,"sourceCodeEnd":3311,"githubUrl":"https://github.com/tiangolo/fastapi/blob/3e8d1526d83a90aaf7d6eb6dc682bf150f180b25/fastapi/routing.py#L3275-L3311","documentation":"Raised in `APIRouter.include_router` (fastapi/routing.py:3293) as `FastAPIError` when `prefix` is empty/falsy AND one of the included router's routes has an empty `path`. FastAPI forbids a route with both empty prefix and empty path because it would be ambiguous (it would match everything). The offending path operation's name is included so you can locate it.","triggerScenarios":"Including a sub-router with no prefix (`include_router(sub)` or `include_router(sub, prefix='')`) when `sub` contains a route declared with `@sub.get('')` or `@sub.route('')`. Also occurs when a sub-router itself was created with an empty path and is included without a prefix.","commonSituations":"Refactoring where a prefix was removed from `include_router` but the route paths were not updated to start with '/'. Declaring `@router.get('')` expecting it to mean '/'. Copying routers between apps and dropping the prefix argument.","solutions":["Add a non-empty prefix on include: `app.include_router(sub, prefix='/sub')`.","Fix the empty route path to use '/': `@sub.get('/')` instead of `@sub.get('')`.","Ensure every path operation in the included router has a path starting with '/'."],"exampleFix":"// before\n@sub.get('')\nasync def root(): ...\napp.include_router(sub)  # prefix empty, path empty\n// after\n@sub.get('/')\nasync def root(): ...\napp.include_router(sub, prefix='/sub')","handlingStrategy":"validation","validationCode":"def safe_include(parent, sub, prefix: str | None) -> None:\n    prefix = prefix or ''\n    if not prefix:\n        for r in getattr(sub, 'routes', []):\n            p = getattr(r, 'path', None)\n            if p is not None and not p:\n                raise ValueError(f'sub-router has an empty path; add a prefix or fix {getattr(r, \"name\", \"?\")}')\n    parent.include_router(sub, prefix=prefix)","typeGuard":"def include_is_safe(sub, prefix: object) -> bool:\n    if isinstance(prefix, str) and prefix:\n        return True\n    return all(getattr(r, 'path', '/') for r in getattr(sub, 'routes', []))","tryCatchPattern":null,"preventionTips":["Always give every path operation a path starting with '/'.","When dropping an include prefix, audit sub-router paths first.","Add a startup smoke test that builds the app to catch include-time errors early."],"tags":["fastapi","routing","configuration","include-router"],"backgroundTag":null,"analyzedSha":"3e8d1526d83a90aaf7d6eb6dc682bf150f180b25","analyzedAt":"2026-08-11T02:34:52.986Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}