feat(asgi): Make integration fully span first compatible #5920
4 issues
High
Iterating over dict without .items() will cause ValueError at runtime - `sentry_sdk/integrations/asgi.py:310-311`
The code iterates over _get_request_attributes(scope) using for attribute, value in ..., but _get_request_attributes returns a dict[str, Any]. Iterating directly over a dict yields only its keys (strings), not key-value pairs. Python will raise ValueError: too many values to unpack or ValueError: not enough values to unpack when trying to unpack single string keys into two variables. This will cause a runtime crash on every ASGI request when span streaming is not enabled.
Return value contract mismatch: _get_request_attributes returns dict but caller unpacks as tuples - `sentry_sdk/integrations/_asgi_common.py:111-137`
The function _get_request_attributes returns a dict[str, Any]. However, in asgi.py line 310, the return value is used as for attribute, value in _get_request_attributes(scope):. Iterating over a dict directly yields only keys, not key-value pairs, causing a ValueError when trying to unpack a single key into two variables (attribute, value). This will crash the ASGI middleware at runtime whenever span streaming is not enabled.
Also found at:
sentry_sdk/integrations/asgi.py:18sentry_sdk/integrations/asgi.py:310-311
Medium
Attribute value is a dict but AttributeValue type does not support dicts - `sentry_sdk/integrations/_asgi_common.py:135`
The client.address attribute is assigned a dictionary value {"REMOTE_ADDR": _get_ip(asgi_scope)}, but the AttributeValue type (defined in _types.py:224-237) only supports primitive types (str, bool, float, int) and their lists/tuples. This type mismatch will likely cause issues when the attribute is serialized or processed by Sentry's telemetry system. The value should be a simple string like _get_ip(asgi_scope) instead.
Inconsistent return type for segment source - returns enum or string depending on code path - `sentry_sdk/integrations/asgi.py:452`
The _get_segment_name_and_source method has inconsistent return types for the source value. Line 452 initializes source as a SegmentSource enum from SEGMENT_SOURCE_FOR_STYLE[segment_style]. However, fallback branches (lines 464, 476, 480) assign SegmentSource.*.value (strings). When an endpoint or route is successfully found (lines 460-461 or 472-473), the source enum is returned unchanged. When used at line 355 with span.set_attribute("sentry.span.source", source), this causes the attribute to sometimes be set to an enum object and sometimes a string, leading to inconsistent telemetry data.
4 skills analyzed
| Skill | Findings | Duration | Cost |
|---|---|---|---|
| code-review | 3 | 7m 6s | $1.00 |
| find-bugs | 1 | 2m 56s | $1.25 |
| skill-scanner | 0 | 1m 37s | $0.44 |
| security-review | 0 | 2m 37s | $0.69 |
Duration: 14m 17s · Tokens: 1.7M in / 25.0k out · Cost: $3.41 (+extraction: $0.01, +merge: $0.00, +fix_gate: $0.01, +dedup: $0.00)