Skip to content

fix(core): Propagate sample_rand when continuing a trace without incoming baggage - #22980

Merged
andreiborza merged 3 commits into
developfrom
ab/fix-sample-rand-continued-trace
Aug 4, 2026
Merged

fix(core): Propagate sample_rand when continuing a trace without incoming baggage#22980
andreiborza merged 3 commits into
developfrom
ab/fix-sample-rand-continued-trace

Conversation

@andreiborza

Copy link
Copy Markdown
Member

What

Fold the scope's sample_rand into the (otherwise empty) frozen Dynamic Sampling Context when continuing a trace that arrived with a sentry-trace header but no Sentry baggage.

  • Continuing such a trace froze an empty DSC, so outgoing requests propagated baggage without sentry-sample_rand.
  • A populated incoming DSC is left untouched.

Why

Without the propagated sample_rand, downstream services generate their own, so sampling decisions can diverge across a single trace. Propagating it keeps the decision consistent end to end.

…ming baggage

When a trace is continued from a `sentry-trace` header with no (or only 3rd-party)
baggage, the frozen Dynamic Sampling Context is empty and previously dropped the
`sample_rand`. Downstream services then received baggage without `sentry-sample_rand`,
so sampling decisions could diverge across the trace. Fold the scope's `sample_rand`
into the otherwise-empty DSC at freeze time; a populated incoming DSC is left untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit fbfdb3d. Configure here.

Comment thread packages/browser/test/tracing/browserTracingIntegration.test.ts Outdated
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 29.91 kB - -
@sentry/browser - with treeshaking flags 28.12 kB - -
@sentry/browser (incl. Tracing) 47.38 kB +0.04% +18 B 🔺
@sentry/browser (incl. Tracing + Span Streaming) 47.38 kB +0.04% +15 B 🔺
@sentry/browser (incl. Tracing, Profiling) 52.15 kB +0.04% +17 B 🔺
@sentry/browser (incl. Tracing, Replay) 86.72 kB +0.03% +19 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 76.15 kB +0.03% +22 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 91.43 kB +0.03% +19 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 104.07 kB +0.03% +21 B 🔺
@sentry/browser (incl. Feedback) 47.22 kB - -
@sentry/browser (incl. sendFeedback) 34.76 kB - -
@sentry/browser (incl. FeedbackAsync) 39.87 kB - -
@sentry/browser (incl. Metrics) 30.99 kB - -
@sentry/browser (incl. Logs) 31.22 kB - -
@sentry/browser (incl. Metrics & Logs) 31.9 kB - -
@sentry/react 31.73 kB - -
@sentry/react (incl. Tracing) 49.65 kB +0.07% +34 B 🔺
@sentry/vue 35 kB +0.06% +20 B 🔺
@sentry/vue (incl. Tracing) 49.37 kB +0.05% +20 B 🔺
@sentry/svelte 29.94 kB - -
CDN Bundle 32.01 kB - -
CDN Bundle (incl. Tracing) 47.75 kB +0.06% +25 B 🔺
CDN Bundle (incl. Logs, Metrics) 33.55 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 49.11 kB +0.06% +26 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 72.9 kB - -
CDN Bundle (incl. Tracing, Replay) 85.38 kB +0.03% +25 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 86.68 kB +0.03% +25 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 91.17 kB +0.04% +30 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 92.48 kB +0.04% +28 B 🔺
CDN Bundle - uncompressed 95.52 kB - -
CDN Bundle (incl. Tracing) - uncompressed 143.18 kB +0.06% +78 B 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed 100.23 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 147.16 kB +0.06% +78 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 224.99 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 262.44 kB +0.03% +78 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 266.4 kB +0.03% +78 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 276.14 kB +0.03% +78 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 280.1 kB +0.03% +78 B 🔺
@sentry/nextjs (client) 52.22 kB +0.03% +13 B 🔺
@sentry/sveltekit (client) 47.82 kB +0.04% +15 B 🔺
@sentry/core/server 80.04 kB +0.04% +25 B 🔺
@sentry/core/browser 52 kB +0.06% +26 B 🔺
@sentry/node 120.91 kB +0.02% +21 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 0 B added added
@sentry/node - without tracing 84.3 kB +0.05% +36 B 🔺
@sentry/aws-serverless 92.96 kB +0.03% +21 B 🔺
@sentry/cloudflare (withSentry) - minified 219.46 kB +0.05% +90 B 🔺
@sentry/cloudflare (withSentry) 540.63 kB +0.03% +161 B 🔺

View base workflow run

…n tests

Compare the frozen DSC's sample_rand against the scope's propagation-context value
instead of only format-checking it, so an implementation that minted a fresh random
would fail.
@andreiborza
andreiborza marked this pull request as ready for review August 4, 2026 09:37
@andreiborza
andreiborza requested review from a team as code owners August 4, 2026 09:37
@andreiborza
andreiborza requested review from a team, Lms24, chargome, logaretm, msonnb and s1gr1d and removed request for a team and s1gr1d August 4, 2026 09:37

@Lms24 Lms24 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm does this solve anything? If we receive a sentry-trace w/o baggage, the head of trace is incompatible with DS or our baggage propagation mechanism. If we, now as a downstream SDK, freeze our sample rand onto the DSC, isn't this just as wrong? 😅

I'm referring to the dev spec where we defined that incoming sentry-trace but no baggage (or baggege but w/o sentry headers) should lead to instant baggage freezing.

@andreiborza

andreiborza commented Aug 4, 2026

Copy link
Copy Markdown
Member Author

@Lms24 this mimics how it behaves today when we have a tracer provider. The PR is preparation work for moving most SDKs off of using tracer providers at all and when doing so existing tests fail.

Here's how this same behavior gets applied on develop, where it also ignores that a DSC might be frozen if I'm not mistaken?

if (hasSpansEnabled()) {
dsc.sampled = String(spanIsSampled(rootSpan));
dsc.sample_rand =
// In OTEL we store the sample rand on the trace state because we cannot access scopes for NonRecordingSpans
// The Sentry OTEL SpanSampler takes care of writing the sample rand on the root span
traceState?.get('sentry.sample_rand') ??
// On all other platforms we can actually get the scopes from a root span (we use this as a fallback)
getCapturedScopesOnSpan(rootSpan).scope?.getPropagationContext().sampleRand.toString();
}

I think there might be a clash in spec, not sure tho 😬

For reference, here's the PR where not having this ended in test failures: #22957

It's not super apparent from this PR alone because tests are using tracer providers still.

@andreiborza
andreiborza requested a review from Lms24 August 4, 2026 10:48

@Lms24 Lms24 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for explaining! Makes sense to me to merge this for now for parity. We should follow up what the expected behaviour is for this case and adjust ours if necessary.

@andreiborza
andreiborza merged commit 0eec199 into develop Aug 4, 2026
517 of 519 checks passed
@andreiborza
andreiborza deleted the ab/fix-sample-rand-continued-trace branch August 4, 2026 11:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants