The Fix
Fixes the handling of `scope['path']` and `scope['root_path']` to conform with ASGI specifications.
Based on closed Kludex/starlette issue #1336 · PR/commit linked
Production note: Most teams hit this during upgrades or environment changes. Roll out with a canary and smoke critical endpoints (health, OpenAPI/docs) before 100%.
@@ -101,9 +101,7 @@ def base_url(self) -> URL:
base_url_scope["path"] = "/"
base_url_scope["query_string"] = b""
- base_url_scope["root_path"] = base_url_scope.get(
- "app_root_path", base_url_scope.get("root_path", "")
- )
from starlette.applications import Starlette
from starlette.responses import PlainTextResponse
from starlette.routing import Route, Mount
class Bar:
async def __call__(self, scope, receive, send):
await PlainTextResponse(f"bar {scope['root_path']=} {scope['path']=}")(scope, receive, send)
class FooBar:
async def __call__(self, scope, receive, send):
await PlainTextResponse(f"foobar {scope['root_path']=} {scope['path']=}")(scope, receive, send)
routes =[
Route('/bar', endpoint=Bar()),
Mount('/foo', routes=[
Route('/bar', endpoint=FooBar())
])
]
app = Starlette(routes=routes)
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
Option A — Apply the official fix\nFixes the handling of `scope['path']` and `scope['root_path']` to conform with ASGI specifications.\nWhen NOT to use: Do not apply this fix if the application relies on the incorrect behavior of path handling.\n\n
Why This Fix Works in Production
- Trigger: In other words, remove anything that doesn't make the bug go away.
- Mechanism: Starlette incorrectly assumes `scope['path']` is a remainder after stripping `scope['root_path']`
- If left unfixed, the same config can fail only in production (env differences), causing startup failures or partial feature outages.
Why This Breaks in Prod
- Starlette incorrectly assumes `scope['path']` is a remainder after stripping `scope['root_path']`
- Production symptom (often without a traceback): In other words, remove anything that doesn't make the bug go away.
Proof / Evidence
- GitHub issue: #1336
- Fix PR: https://github.com/kludex/starlette/pull/2352
- Reproduced locally: No (not executed)
- Last verified: 2026-02-11
- Confidence: 0.80
- Did this fix it?: Yes (upstream fix exists)
- Own content ratio: 0.52
Discussion
High-signal excerpts from the issue thread (symptoms, repros, edge-cases).
“Take in consideration that I'll need a lot of references to follow on this, and to understand the implications for our users. But yeah, help…”
“Hello @Kludex :wave: I would be interested to help tackling this issue; if you need a hand, let me know :)”
Failure Signature (Search String)
- In other words, remove anything that doesn't make the bug go away.
- 1. `scope['path']` does not include `scope['root_path']` , which is ASGI incompatible.
Copy-friendly signature
Failure Signature
-----------------
In other words, remove anything that doesn't make the bug go away.
1. `scope['path']` does not include `scope['root_path']` , which is ASGI incompatible.
Error Message
Signature-only (no traceback captured)
Error Message
-------------
In other words, remove anything that doesn't make the bug go away.
1. `scope['path']` does not include `scope['root_path']` , which is ASGI incompatible.
Minimal Reproduction
from starlette.applications import Starlette
from starlette.responses import PlainTextResponse
from starlette.routing import Route, Mount
class Bar:
async def __call__(self, scope, receive, send):
await PlainTextResponse(f"bar {scope['root_path']=} {scope['path']=}")(scope, receive, send)
class FooBar:
async def __call__(self, scope, receive, send):
await PlainTextResponse(f"foobar {scope['root_path']=} {scope['path']=}")(scope, receive, send)
routes =[
Route('/bar', endpoint=Bar()),
Mount('/foo', routes=[
Route('/bar', endpoint=FooBar())
])
]
app = Starlette(routes=routes)
What Broke
ASGI compatibility issues cause incorrect routing and response paths.
Why It Broke
Starlette incorrectly assumes `scope['path']` is a remainder after stripping `scope['root_path']`
Fix Options (Details)
Option A — Apply the official fix
Fixes the handling of `scope['path']` and `scope['root_path']` to conform with ASGI specifications.
Fix reference: https://github.com/kludex/starlette/pull/2352
Last verified: 2026-02-11. Validate in your environment.
When NOT to Use This Fix
- Do not apply this fix if the application relies on the incorrect behavior of path handling.
Verify Fix
Re-run the minimal reproduction on your broken version, then apply the fix and re-run.
Did This Fix Work in Your Case?
Quick signal helps us prioritize which fixes to verify and improve.
Prevention
- Add a TLS smoke test that performs a real handshake in CI (include CA bundle validation and hostname checks).
- Alert on handshake failures by error string and endpoint to catch cert/CA changes quickly.
Related Issues
No related fixes found.
Sources
We don’t republish the full GitHub discussion text. Use the links above for context.