Skip to content

fix(starlette): Stop duplicating scope["root_path"] in URLs#6579

Merged
alexander-alderman-webb merged 22 commits into
masterfrom
webb/asgi/double-mount-prefix
Jun 26, 2026
Merged

fix(starlette): Stop duplicating scope["root_path"] in URLs#6579
alexander-alderman-webb merged 22 commits into
masterfrom
webb/asgi/double-mount-prefix

fix quart url

518acbe
Select commit
Loading
Failed to load commit list.
@sentry/warden / warden: find-bugs completed Jun 19, 2026 in 0s

2 issues

find-bugs: Found 2 issues (1 medium, 1 low)

Medium

Sentry ASGI middleware silently skipped when Quart version cannot be determined - `sentry_sdk/integrations/quart.py:20`

patch_asgi_app() now computes version = package_version("quart") and bails out of instrumentation entirely when version is None. Previously the middleware always wrapped Quart.__call__ (guarded only by whether the integration was enabled). With this change, if the installed Quart package has no resolvable version metadata, package_version returns None and the or version is None clause makes sentry_patched_asgi_app fall through to old_app without the SentryAsgiMiddleware, silently disabling error/transaction capture. A safer approach is to keep instrumenting and pick a conservative default for path_includes_root_path (e.g. version >= (0, 19) if version is not None else False) instead of skipping the middleware.

Also found at:

  • sentry_sdk/integrations/quart.py:97-99

Low

Starlette test_request_url does not exercise root_path deduplication — the actual regression scenario - `tests/integrations/fastapi/test_fastapi.py:1065`

The new test_request_url in tests/integrations/starlette/test_starlette.py uses TestClient(starlette_app) without a root_path argument, so the ASGI scope["root_path"] is always "". The /root in the requested path /root/nomessage is just a normal path segment, not a mounted root path. Because of this, both the old (buggy) and new code produce identical URLs, so the test passes even without the fix and would not catch a regression of the duplicated root_path. The litestar test correctly sets root_path="/root" on its TestClient, which is the only way to trigger the duplication logic.


⏱ 19m 48s · 3.6M in / 179.3k out · $5.56

Annotations

Check warning on line 20 in sentry_sdk/integrations/quart.py

See this annotation in the file changed.

@sentry-warden sentry-warden / warden: find-bugs

Sentry ASGI middleware silently skipped when Quart version cannot be determined

`patch_asgi_app()` now computes `version = package_version("quart")` and bails out of instrumentation entirely when `version is None`. Previously the middleware always wrapped `Quart.__call__` (guarded only by whether the integration was enabled). With this change, if the installed Quart package has no resolvable version metadata, `package_version` returns `None` and the `or version is None` clause makes `sentry_patched_asgi_app` fall through to `old_app` without the `SentryAsgiMiddleware`, silently disabling error/transaction capture. A safer approach is to keep instrumenting and pick a conservative default for `path_includes_root_path` (e.g. `version >= (0, 19) if version is not None else False`) instead of skipping the middleware.

Check warning on line 99 in sentry_sdk/integrations/quart.py

See this annotation in the file changed.

@sentry-warden sentry-warden / warden: find-bugs

[NV3-C86] Sentry ASGI middleware silently skipped when Quart version cannot be determined (additional location)

`patch_asgi_app()` now computes `version = package_version("quart")` and bails out of instrumentation entirely when `version is None`. Previously the middleware always wrapped `Quart.__call__` (guarded only by whether the integration was enabled). With this change, if the installed Quart package has no resolvable version metadata, `package_version` returns `None` and the `or version is None` clause makes `sentry_patched_asgi_app` fall through to `old_app` without the `SentryAsgiMiddleware`, silently disabling error/transaction capture. A safer approach is to keep instrumenting and pick a conservative default for `path_includes_root_path` (e.g. `version >= (0, 19) if version is not None else False`) instead of skipping the middleware.