Skip to content

fix(tracing): Skip duplicate navigation span from withAnchor POP_TO#6439

Open
antonis wants to merge 7 commits into
mainfrom
fix/duplicate-popto-navigation-span-6434
Open

fix(tracing): Skip duplicate navigation span from withAnchor POP_TO#6439
antonis wants to merge 7 commits into
mainfrom
fix/duplicate-popto-navigation-span-6434

Conversation

@antonis

@antonis antonis commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

📢 Type of change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring

📜 Description

The fix skips starting a navigation span for a POP_TO whose target is the route we are already on

💡 Motivation and Context

Fixes #6434

💚 How did you test it?

CI, Manual

📝 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.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.
  • No breaking changes.

🔮 Next steps

…6434)

Expo Router's `withAnchor` navigations can emit a second `POP_TO` dispatch
to the destination route purely to stamp `initial: false` onto it. Since
`startIdleNavigationSpan` runs on every `__unsafe_action__` dispatch and
`POP_TO` was not filtered, this bookkeeping dispatch started a second idle
navigation span that lingered until timeout and was sent as a spurious
duplicate transaction (sometimes capturing in-flight HTTP/TTID children).

Skip starting a navigation span for a `POP_TO` whose target is the route we
are already on. The current route name is read from React Navigation's own
`getCurrentRoute()` (raw name, same namespace as the action payload) rather
than `latestRoute`, whose name may be rewritten by a route override provider
such as Expo Router. Genuine `popTo`/`dismissTo` navigations to a different
route are unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@antonis
antonis force-pushed the fix/duplicate-popto-navigation-span-6434 branch from 864ccd2 to 2dd9cc9 Compare July 10, 2026 12:28
@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

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(tracing): Skip duplicate navigation span from withAnchor POP_TO by antonis in #6439
  • chore(deps): bump actions/setup-node from 6.4.0 to 7.0.0 by dependabot in #6463
  • chore(deps): bump json from 2.17.1.2 to 2.19.9 in /performance-tests by dependabot in #6512
  • chore(deps): update CLI to v3.6.2 by github-actions in #6511
  • chore(deps): update Sentry Android Gradle Plugin to v6.16.0 by github-actions in #6508
  • chore(deps): update Android SDK to v8.50.1 by github-actions in #6503

🤖 This preview updates automatically when you update the PR.

@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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 2dd9cc9. Configure here.

@antonis antonis added the ready-to-merge Triggers the full CI test suite label Jul 10, 2026
@sentry

sentry Bot commented Jul 10, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
Sentry RN io.sentry.reactnative.sample 8.20.0 (100) Release

⚙️ sentry-react-native Build Distribution Settings

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

iOS (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 3846.15 ms 1217.85 ms -2628.30 ms
Size 4.98 MiB 6.55 MiB 1.57 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
21a1e70+dirty 3834.15 ms 1218.43 ms -2615.73 ms
882f8ae+dirty 3840.30 ms 1224.41 ms -2615.88 ms
15d4514+dirty 3840.17 ms 1225.79 ms -2614.38 ms
0b5a379+dirty 3828.91 ms 1214.12 ms -2614.79 ms
f3215d3+dirty 3842.73 ms 1219.33 ms -2623.40 ms
ab203f9+dirty 3848.07 ms 1219.71 ms -2628.35 ms
6177334+dirty 3834.85 ms 1217.58 ms -2617.28 ms
5257d80+dirty 3854.39 ms 1234.28 ms -2620.11 ms
9474ead+dirty 3864.29 ms 1223.55 ms -2640.74 ms
1122a96+dirty 3823.10 ms 1218.64 ms -2604.46 ms

App size

Revision Plain With Sentry Diff
21a1e70+dirty 4.98 MiB 6.46 MiB 1.49 MiB
882f8ae+dirty 5.15 MiB 6.70 MiB 1.54 MiB
15d4514+dirty 5.15 MiB 6.70 MiB 1.55 MiB
0b5a379+dirty 5.15 MiB 6.70 MiB 1.54 MiB
f3215d3+dirty 5.15 MiB 6.67 MiB 1.52 MiB
ab203f9+dirty 4.98 MiB 6.51 MiB 1.53 MiB
6177334+dirty 5.15 MiB 6.68 MiB 1.53 MiB
5257d80+dirty 5.15 MiB 6.69 MiB 1.54 MiB
9474ead+dirty 5.15 MiB 6.71 MiB 1.55 MiB
1122a96+dirty 5.15 MiB 6.68 MiB 1.53 MiB

Previous results on branch: fix/duplicate-popto-navigation-span-6434

Startup times

Revision Plain With Sentry Diff
542850a+dirty 3850.38 ms 1235.64 ms -2614.74 ms

App size

Revision Plain With Sentry Diff
542850a+dirty 4.98 MiB 6.53 MiB 1.55 MiB

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Android (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 437.57 ms 480.68 ms 43.12 ms
Size 49.74 MiB 55.36 MiB 5.62 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
a5d243c+dirty 424.52 ms 485.18 ms 60.66 ms
e5bb5f6+dirty 430.09 ms 459.96 ms 29.87 ms
7ac3378+dirty 404.78 ms 439.84 ms 35.06 ms
5789645+dirty 426.82 ms 495.42 ms 68.60 ms
853723c+dirty 405.54 ms 440.08 ms 34.54 ms
61cc206+dirty 522.33 ms 553.98 ms 31.65 ms
44c8b3f+dirty 414.20 ms 457.28 ms 43.08 ms
68ae91b+dirty 416.44 ms 477.56 ms 61.12 ms
7a89652+dirty 537.76 ms 567.84 ms 30.08 ms
b0d3373+dirty 557.66 ms 579.42 ms 21.76 ms

App size

Revision Plain With Sentry Diff
a5d243c+dirty 48.30 MiB 53.54 MiB 5.23 MiB
e5bb5f6+dirty 49.74 MiB 55.09 MiB 5.34 MiB
7ac3378+dirty 43.75 MiB 48.13 MiB 4.37 MiB
5789645+dirty 49.74 MiB 54.85 MiB 5.11 MiB
853723c+dirty 48.30 MiB 53.58 MiB 5.28 MiB
61cc206+dirty 49.74 MiB 55.36 MiB 5.62 MiB
44c8b3f+dirty 48.30 MiB 53.46 MiB 5.15 MiB
68ae91b+dirty 49.74 MiB 54.79 MiB 5.05 MiB
7a89652+dirty 48.30 MiB 53.60 MiB 5.30 MiB
b0d3373+dirty 48.30 MiB 53.58 MiB 5.28 MiB

Previous results on branch: fix/duplicate-popto-navigation-span-6434

Startup times

Revision Plain With Sentry Diff
542850a+dirty 431.73 ms 494.18 ms 62.45 ms

App size

Revision Plain With Sentry Diff
542850a+dirty 49.74 MiB 55.26 MiB 5.52 MiB

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Android (new) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 420.96 ms 490.80 ms 69.84 ms
Size 49.74 MiB 55.36 MiB 5.62 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
1e5d96d+dirty 423.33 ms 482.46 ms 59.13 ms
a5d243c+dirty 499.20 ms 525.62 ms 26.42 ms
ecf47a2+dirty 457.21 ms 498.10 ms 40.89 ms
a0d8cf8+dirty 533.71 ms 564.25 ms 30.54 ms
f170ec3+dirty 505.96 ms 551.88 ms 45.92 ms
9474ead+dirty 432.18 ms 481.92 ms 49.73 ms
c151573+dirty 485.39 ms 495.18 ms 9.79 ms
7436d0f+dirty 429.58 ms 452.52 ms 22.94 ms
4e0b819+dirty 599.31 ms 654.31 ms 55.00 ms
5a23c47+dirty 406.83 ms 451.47 ms 44.64 ms

App size

Revision Plain With Sentry Diff
1e5d96d+dirty 49.74 MiB 54.81 MiB 5.07 MiB
a5d243c+dirty 48.30 MiB 53.54 MiB 5.23 MiB
ecf47a2+dirty 49.74 MiB 54.82 MiB 5.07 MiB
a0d8cf8+dirty 48.30 MiB 53.49 MiB 5.19 MiB
f170ec3+dirty 48.30 MiB 53.57 MiB 5.26 MiB
9474ead+dirty 48.30 MiB 53.61 MiB 5.30 MiB
c151573+dirty 48.30 MiB 53.54 MiB 5.24 MiB
7436d0f+dirty 48.30 MiB 53.60 MiB 5.30 MiB
4e0b819+dirty 49.74 MiB 54.81 MiB 5.07 MiB
5a23c47+dirty 49.74 MiB 54.82 MiB 5.07 MiB

Previous results on branch: fix/duplicate-popto-navigation-span-6434

Startup times

Revision Plain With Sentry Diff
542850a+dirty 433.90 ms 497.21 ms 63.32 ms

App size

Revision Plain With Sentry Diff
542850a+dirty 49.74 MiB 55.26 MiB 5.52 MiB

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

iOS (new) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 3858.04 ms 1239.92 ms -2618.12 ms
Size 4.98 MiB 6.55 MiB 1.57 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
ae37560+dirty 3840.10 ms 1217.89 ms -2622.21 ms
e763471+dirty 3826.10 ms 1221.52 ms -2604.58 ms
0b1b5e3+dirty 3820.72 ms 1207.94 ms -2612.78 ms
5ca03f9+dirty 3873.76 ms 1236.26 ms -2637.51 ms
acd838e+dirty 3835.94 ms 1215.87 ms -2620.07 ms
5789645+dirty 3841.36 ms 1214.81 ms -2626.55 ms
61cc206+dirty 3822.60 ms 1206.17 ms -2616.43 ms
a2585ce+dirty 3837.98 ms 1214.20 ms -2623.77 ms
bc8f61e+dirty 3849.87 ms 1221.19 ms -2628.68 ms
5b7e8a7+dirty 3855.46 ms 1234.47 ms -2620.99 ms

App size

Revision Plain With Sentry Diff
ae37560+dirty 5.15 MiB 6.70 MiB 1.54 MiB
e763471+dirty 4.98 MiB 6.51 MiB 1.53 MiB
0b1b5e3+dirty 5.15 MiB 6.70 MiB 1.54 MiB
5ca03f9+dirty 4.98 MiB 6.53 MiB 1.55 MiB
acd838e+dirty 5.15 MiB 6.70 MiB 1.55 MiB
5789645+dirty 4.98 MiB 6.50 MiB 1.52 MiB
61cc206+dirty 4.98 MiB 6.55 MiB 1.57 MiB
a2585ce+dirty 4.98 MiB 6.55 MiB 1.57 MiB
bc8f61e+dirty 4.98 MiB 6.47 MiB 1.49 MiB
5b7e8a7+dirty 5.15 MiB 6.70 MiB 1.54 MiB

Previous results on branch: fix/duplicate-popto-navigation-span-6434

Startup times

Revision Plain With Sentry Diff
542850a+dirty 3828.55 ms 1220.92 ms -2607.63 ms

App size

Revision Plain With Sentry Diff
542850a+dirty 4.98 MiB 6.53 MiB 1.55 MiB

@antonis antonis left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Marking as blocked in favour of #6472 for now. If the later lands I'll close this

antonis and others added 2 commits July 24, 2026 12:29
Replace the dispatch-time-only, leaf-name dedup with the more complete
two-guard design from #6472, plus a refinement that closes a
false-suppression regression both prior approaches shared.

- Dispatch-time guard (`isRouteFocused`): skip a `POP_TO` whose target is
  already focused on the active route chain AND that carries the `withAnchor`
  marker (`params.initial === false`). Requiring the marker is what lets a
  genuine `popTo` to an earlier same-named route in the stack (e.g. `[id]` →
  `[id]`, different `route.key`) through, since those never carry `initial`.
- State-change guard: discard a `POP_TO` span that landed on the same
  `route.key` (a bookkeeping dispatch that slipped past the dispatch-time
  filter, e.g. a nested payload name), unless a deep link claimed it. Keyed
  on `route.key`, so it never affects a navigation that changed the route.

`applyPendingDeepLinkToSpan` now returns whether it attached, so the
state-change guard can preserve deep-link-to-current-screen attribution.

Co-authored-by: Cryptoteep <cryptoteep@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread packages/core/src/js/tracing/reactnavigation.ts
Comment thread packages/core/src/js/tracing/reactnavigation.ts
- Preserve deep-link attribution on a same-route POP_TO: check the
  `taggedDeepLinkSpans` set instead of the just-attached result, so a span
  tagged earlier via the synchronous late-arrival listener is not discarded
  (revert `applyPendingDeepLinkToSpan` back to `void`). Reported by cursor bot.
- End `navigationProcessingSpan` before dropping it in
  `_discardLatestTransaction` so the bookkeeping-discard path does not leave
  an unfinished span dangling. Reported by sentry bot.
- Add a test that a same-route POP_TO carrying a deep link is kept.

Co-authored-by: Cryptoteep <cryptoteep@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <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.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit afeba2a. Configure here.

Comment thread packages/core/test/tracing/reactnavigation.test.ts
…#6434)

The test used `emitNavigationWithoutStateChange()`, whose payload-less
NAVIGATE is rejected by the `!dispatchedRouteName` guard under
`useDispatchedActionData: true`, so no in-flight span was ever created and
the assertion was trivially true. Start a real in-flight navigation via a
payloaded NAVIGATE dispatch (no state change) so the test genuinely exercises
the focused-route POP_TO not tearing it down. Verified it fails when the
dispatch-time guard is removed. Reported by warden bot.

Co-authored-by: Cryptoteep <cryptoteep@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@antonis
antonis marked this pull request as ready for review July 24, 2026 12:42

@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 a7204aa. Configure here.

Comment thread packages/core/src/js/tracing/reactnavigation.ts
…hedActionData (#6434)

The two guards were keyed off `navigationActionType` / the span's action-type
attribute, both only populated when `useDispatchedActionData` is enabled. That
option defaults off for `expoRouterIntegration` and the Expo sample, so the
duplicate POP_TO transaction still occurred on the default setup where the bug
was reported (confirmed: 2 transactions with the flag off).

Drive the dispatch-time guard off `actionType` (parsed unconditionally) and
track the latest navigation span's action type in a closure variable for the
state-change discard, so both guards work regardless of the flag. The span
attribute stays flag-gated to avoid changing trace metadata for existing users.
The guards remain narrow: guard 1 requires `params.initial === false` (only set
by withAnchor), guard 2 only discards a same-route-key POP_TO (a no-op pop).

Add a test asserting the default (flag-off) setup no longer creates the
duplicate transaction.

Co-authored-by: Cryptoteep <cryptoteep@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@antonis antonis removed the Blocked label Jul 24, 2026
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.

withAnchor's internal POP_TO bookkeeping dispatch creates a spurious duplicate navigation span

1 participant