fix: Introduce _get_current_streamed_span() to keep types backwards compatible
#6177
2 issues
High
NoOpStreamedSpan guard is dead code; get_traceparent will operate on no-op spans - `sentry_sdk/scope.py:587-589`
The condition was changed to use self.streamed_span for the not-None check, but the isinstance(self.span, NoOpStreamedSpan) check still references self.span. The self.span property returns None whenever self._span is a StreamedSpan (including NoOpStreamedSpan), because its getter filters by isinstance(self._span, Span). Since isinstance(None, NoOpStreamedSpan) is always False, the guard never short-circuits, so when a NoOpStreamedSpan is active the code falls through to self.streamed_span._to_traceparent() instead of using the propagation context. This produces incorrect traceparent headers for unsampled/no-op spans, breaking distributed tracing fidelity.
Also found at:
sentry_sdk/scope.py:605-607
NoOpStreamedSpan guard is dead code in get_traceparent — calls _to_traceparent on no-op spans - `sentry_sdk/scope.py:587-589`
The guard not isinstance(self.span, NoOpStreamedSpan) mixes two mutually-exclusive properties. The span property returns self._span only when it's a Span (line 884), while streamed_span returns self._span only when it's a StreamedSpan (line 901). When self.streamed_span is not None, self._span is a StreamedSpan, so self.span returns None, and isinstance(None, NoOpStreamedSpan) is always False. The guard never trips, so _to_traceparent() will be invoked on a NoOpStreamedSpan (which is a subclass of StreamedSpan, traces.py:556), producing incorrect traceparent headers in no-op tracing scenarios.
Also found at:
sentry_sdk/scope.py:605-607
4 skills analyzed
| Skill | Findings | Duration | Cost |
|---|---|---|---|
| code-review | 1 | 2m 31s | $2.29 |
| find-bugs | 1 | 1m 26s | $3.14 |
| skill-scanner | 0 | 1m 51s | $1.12 |
| security-review | 0 | 1m 31s | $1.39 |
Duration: 7m 19s · Tokens: 1.7M in / 19.3k out · Cost: $7.95 (+merge: $0.00, +dedup: $0.01)