Skip to content

fix(core): App start data lost when first transaction is unsampled#5756

Merged
antonis merged 6 commits intomainfrom
fix/app-start-unsampled-span
Mar 5, 2026
Merged

fix(core): App start data lost when first transaction is unsampled#5756
antonis merged 6 commits intomainfrom
fix/app-start-unsampled-span

Conversation

@antonis
Copy link
Contributor

@antonis antonis commented Mar 4, 2026

📢 Type of change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring

📜 Description

When tracesSampleRate < 1.0, the appStartIntegration locks firstStartedActiveRootSpanId to the first root span regardless of whether it is sampled. Since processEvent only runs for sampled events, if the first root span is unsampled, app start data is permanently lost for that session — subsequent sampled transactions fail the span ID match check.

This PR adds a spanIsSampled() guard in recordFirstStartedActiveRootSpanId so the ID only locks to the first sampled root span. The existing age/duration guards still protect against stale app starts.

💡 Motivation and Context

Users with tracesSampleRate < 1.0 were losing Cold/Warm Start data whenever the first transaction happened to be unsampled (which is statistically likely at low sample rates). This is a data loss bug — the app start is measured by the native layer but never attached to any event.

Fixes #5757

💚 How did you test it?

  • Added unit test: "Does not lock firstStartedActiveRootSpanId to unsampled root span" — emits a SentryNonRecordingSpan (unsampled) followed by a real sampled span, verifies app start attaches to the sampled transaction
  • All existing tests pass (yarn test, yarn build, yarn lint)

📝 Checklist

  • I added tests to verify changes
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • All tests passing
  • No breaking changes

🔮 Next steps

🤖 Generated with Claude Code

… app start

When `tracesSampleRate < 1.0`, the first root span could be unsampled,
permanently locking `firstStartedActiveRootSpanId` to a span that would
never reach `processEvent`. This caused app start data to be lost for
the entire session. Now we check `spanIsSampled()` before locking the ID,
so app start attaches to the first sampled root span instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Contributor

github-actions bot commented Mar 4, 2026

Semver Impact of This PR

None (no version bump detected)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


  • fix(core): App start data lost when first transaction is unsampled by antonis in #5756
  • Add 'agents.toml' to skip list in CI workflow by lucas-zimerman in #5774
  • EAS Build Hooks by alwx in #5666
  • chore(deps): update CLI to v3.3.0 by github-actions in #5762
  • chore(deps): update Cocoa SDK to v9.6.0 by github-actions in #5759
  • [iOS + Android] Add the ability to intercept errors from native side and forward them to JS console by alwx in #5622
  • Feat(Expo): Add expo constants on event context. by lucas-zimerman in #5748
  • chore(deps): update JavaScript SDK to v10.42.0 by github-actions in #5753
  • feat(core): Capture dynamic route params as span attributes by antonis in #5750
  • chore(deps): bump brace-expansion from 1.1.11 to 1.1.12 by dependabot in #5751
  • chore(deps): bump minimatch to fix ReDoS vulnerabilities and tmp to ^0.2.4 by antonis in #5749
  • chore(deps): bump getsentry/craft/.github/workflows/changelog-preview.yml from 2.21.7 to 2.23.1 by dependabot in #5738
  • chore(deps): update Wizard to v6.12.0 by github-actions in #5747
  • chore(deps): update JavaScript SDK to v10.41.0 by github-actions in #5744
  • chore(deps): bump tar to ^7.5.8 by antonis in #5703
  • chore(deps): bump js-yaml to fix prototype pollution in merge by antonis in #5709
  • chore(deps): bump ajv to fix ReDoS in $data option by antonis in #5710
  • chore(deps): update CLI to v3.2.3 by github-actions in #5743
  • Fixes the issue with unit mismatch in adjustTransactionDuration by alwx in #5740
  • Handle inactive state for spans by alwx in #5742
  • chore(deps): bump actions/github-script from 7 to 8 by dependabot in #5737
  • chore(deps): bump actions/upload-artifact from 6 to 7 by dependabot in #5739
  • chore(deps): bump futureware-tech/simulator-action from 4 to 5 by dependabot in #5735
  • chore(deps): bump actions/download-artifact from 7 to 8 by dependabot in #5736

Plus 11 more


🤖 This preview updates automatically when you update the PR.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@antonis antonis marked this pull request as ready for review March 4, 2026 12:43
Copy link
Contributor

@alwx alwx left a comment

Choose a reason for hiding this comment

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

looks good to me!

@antonis antonis added the ready-to-merge Triggers the full CI test suite label Mar 5, 2026
@lucas-zimerman
Copy link
Collaborator

q: what about users with sample rate near 0, aren't they going to lose the app start data anyway?

Copy link
Collaborator

@lucas-zimerman lucas-zimerman left a comment

Choose a reason for hiding this comment

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

lgtm

@antonis
Copy link
Contributor Author

antonis commented Mar 5, 2026

q: what about users with sample rate near 0, aren't they going to lose the app start data anyway?

Good point @lucas-zimerman 👍
Users with with sample rate near 0 would lose the app data. This fix just ensures app start is included when they do get a sampled transaction improving the current functionality.
I'll revisit this and open a separate PR.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

iOS (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 1215.63 ms 1221.65 ms 6.02 ms
Size 3.38 MiB 4.81 MiB 1.42 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
ea3e26e+dirty 1229.13 ms 1228.46 ms -0.67 ms
80e4616+dirty 1221.32 ms 1225.64 ms 4.32 ms
818a608+dirty 1205.76 ms 1208.00 ms 2.24 ms
77061ed+dirty 1233.16 ms 1234.88 ms 1.71 ms
bef3709+dirty 1222.07 ms 1220.24 ms -1.83 ms
a206511+dirty 1185.00 ms 1186.35 ms 1.35 ms
74979ac+dirty 1210.49 ms 1213.31 ms 2.82 ms
a2bb688+dirty 1223.53 ms 1232.90 ms 9.37 ms
8a868fe+dirty 1221.50 ms 1230.78 ms 9.28 ms
d590428+dirty 1211.77 ms 1220.51 ms 8.75 ms

App size

Revision Plain With Sentry Diff
ea3e26e+dirty 3.41 MiB 4.58 MiB 1.17 MiB
80e4616+dirty 3.38 MiB 4.60 MiB 1.22 MiB
818a608+dirty 2.63 MiB 3.91 MiB 1.28 MiB
77061ed+dirty 2.63 MiB 3.98 MiB 1.34 MiB
bef3709+dirty 3.38 MiB 4.78 MiB 1.40 MiB
a206511+dirty 3.41 MiB 4.67 MiB 1.25 MiB
74979ac+dirty 3.38 MiB 4.60 MiB 1.22 MiB
a2bb688+dirty 2.63 MiB 3.99 MiB 1.36 MiB
8a868fe+dirty 3.38 MiB 4.60 MiB 1.22 MiB
d590428+dirty 3.38 MiB 4.78 MiB 1.39 MiB

@antonis antonis enabled auto-merge (squash) March 5, 2026 11:50
@antonis antonis merged commit 4cebd92 into main Mar 5, 2026
31 of 72 checks passed
@antonis antonis deleted the fix/app-start-unsampled-span branch March 5, 2026 12:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-to-merge Triggers the full CI test suite

Projects

None yet

Development

Successfully merging this pull request may close these issues.

App Start data lost when first transaction is unsampled

3 participants