Skip to content

🐛 Fix scope['route'].path/.path_format to include include_router() prefixes - #16176

Open
SAURABHSALVE wants to merge 1 commit into
fastapi:masterfrom
SAURABHSALVE:fix/scope-route-path-includes-prefix
Open

🐛 Fix scope['route'].path/.path_format to include include_router() prefixes#16176
SAURABHSALVE wants to merge 1 commit into
fastapi:masterfrom
SAURABHSALVE:fix/scope-route-path-includes-prefix

Conversation

@SAURABHSALVE

Copy link
Copy Markdown
Contributor

Summary

Fixes regression since 0.137.0 where HTTP routes added via include_router() had request.scope[route].path / .path_format lose all include-time prefixes, while WebSocket routes retained them (inconsistent behavior).

Closes #16051

Root Cause

When an _EffectiveRouteContext (carrying the full prefixed path) is present during routing, three sites in fastapi/routing.py still wrote the original, unprefixed APIRoute into scope[route]:

  • APIRoute.matches()
  • _IncludedRouter._handle_selected()
  • APIRouter.app() low-priority branch

Solution

Use the existing public RouteContext facade (defined for iter_route_contexts()) to wrap the route object when an effective context applies. RouteContext proxies .path/.path_format to the effective context while preserving .original_route for escape-hatch access.

Testing

  • Added 4 focused regression tests in test_route_scope.py:
    • Single-level include_router() with prefix
    • WebSocket parity
    • Nested router prefixes
    • Middleware-observed scope case (real-world instrumentation use case)
  • All new tests fail without fix, pass with it (verified via stash/pop)
  • Full suite: 3328 passed, 19 skipped, 5 xfailed

Note

scope[route] type changes from APIRoute to RouteContext for included routes only (direct app routes unaffected). Attribute access is proxied; existing code accessing .path/.name etc. works unchanged. isinstance(scope[route], APIRoute) checks would need adjustment to use .original_route if needed, but this is precedent—WebSocket routes under include already return rebuilt instances.

@codspeed-hq

codspeed-hq Bot commented Aug 10, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 24 untouched benchmarks


Comparing SAURABHSALVE:fix/scope-route-path-includes-prefix (5dae385) with master (b963df2)1

Open in CodSpeed

Footnotes

  1. No successful run was found on master (a9134f6) during the generation of this report, so b963df2 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@SAURABHSALVE
SAURABHSALVE force-pushed the fix/scope-route-path-includes-prefix branch 2 times, most recently from 7de83b4 to 5dae385 Compare August 10, 2026 11:35
…efixes

Regression since 0.137.0 (PR fastapi#15745): include_router() prefixes were lost from
scope["route"].path and .path_format on HTTP routes, while WebSocket routes
retained them. This caused inconsistent behavior and metrics/tracing label
collapse when multiple included routers had identically-named endpoints.

Root cause: APIRoute.matches(), _IncludedRouter._handle_selected(), and
APIRouter.app() were writing the original unprefixed APIRoute into scope["route"]
even when an _EffectiveRouteContext carrying the full prefixed path applied.

Fix: Use the existing public RouteContext facade (already used by
iter_route_contexts) to proxy .path/.path_format to the effective context
while preserving access to .original_route.

Fixes: fastapi#16051
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant