Skip to content

Merge branch 'master' into ivana/span-first-18-trace-propagation

98abb6a
Select commit
Loading
Failed to load commit list.
Merged

ref: Support outgoing trace propagation in span first (18) #5638

Merge branch 'master' into ivana/span-first-18-trace-propagation
98abb6a
Select commit
Loading
Failed to load commit list.
@sentry/warden / warden completed Mar 12, 2026 in 13m 58s

5 issues

High

NoOpStreamedSpan._iter_headers() raises AttributeError due to uninitialized _segment - `sentry_sdk/traces.py:504-512`

The new _iter_headers() method accesses self._segment but NoOpStreamedSpan does not initialize this attribute (it doesn't call super().__init__() and only sets _scope, _unsampled_reason, and _finished). In scope.py:688, span._iter_headers() is called without a guard against NoOpStreamedSpan, unlike _to_baggage() (line 607) and _get_trace_context() (line 621) which have not isinstance(self.span, NoOpStreamedSpan) checks. When iter_trace_propagation_headers() is called while a NoOpStreamedSpan is active, this will raise AttributeError: 'NoOpStreamedSpan' object has no attribute '_segment'.

NoOpStreamedSpan missing _segment attribute causes AttributeError in inherited methods - `sentry_sdk/traces.py:504-512`

The new _iter_headers(), _to_baggage(), and _dynamic_sampling_context() methods access self._segment, but NoOpStreamedSpan.__init__() does not initialize this attribute. When these inherited methods are called on a NoOpStreamedSpan instance (e.g., through scope.iter_trace_propagation_headers() which doesn't guard against NoOpStreamedSpan), an AttributeError will be raised, crashing HTTP client integrations (stdlib, httpx, aiohttp, grpc, celery, etc.).

Also found at:

  • sentry_sdk/traces.py:492-502
  • sentry_sdk/traces.py:514-529
  • sentry_sdk/tracing_utils.py:1123-1124

Medium

Inconsistent handling of NoOpStreamedSpan between transaction setter and set_transaction_name - `sentry_sdk/scope.py:827-836`

The set_transaction_name method (lines 841-856) explicitly checks for NoOpStreamedSpan first and silently returns, then separately handles StreamedSpan. However, the transaction setter (lines 826-836) only checks for StreamedSpan without explicitly handling NoOpStreamedSpan first. Since NoOpStreamedSpan is a subclass of StreamedSpan, this causes NoOpStreamedSpan to trigger a deprecation warning in the setter, which is inconsistent with the silent handling in set_transaction_name. Users with NoOpStreamedSpan (unsampled traces) will see unexpected deprecation warnings.

Also found at:

  • sentry_sdk/scope.py:833

Low

Inconsistent use of self._span vs self.span in get_trace_context - `sentry_sdk/scope.py:620-621`

In get_trace_context, line 620 checks self._span is not None but line 621 checks isinstance(self.span, NoOpStreamedSpan), mixing the private attribute with the public property. This is inconsistent with get_traceparent and get_baggage which consistently use self.span throughout. While currently functionally equivalent (since self.span just returns self._span), this inconsistency could cause subtle issues if the property behavior changes in the future.

Redundant Pattern import immediately overwritten - `sentry_sdk/tracing_utils.py:11`

Line 11 imports Pattern from typing, but this import is immediately overwritten by the try/except block at lines 15-19 which imports Pattern from re (Python 3.7+) or typing (Python 3.6 fallback). The import at line 11 serves no purpose since Python's module-level imports are executed sequentially and the later import overwrites it.

4 skills analyzed
Skill Findings Duration Cost
code-review 2 9m 35s $4.59
find-bugs 3 13m 44s $10.25
skill-scanner 0 2m 34s $1.58
security-review 0 13m 28s $1.51

Duration: 39m 22s · Tokens: 13.0M in / 121.2k out · Cost: $17.95 (+extraction: $0.01, +merge: $0.00, +fix_gate: $0.01, +dedup: $0.01)