Skip to content

fix(core): Deduplicate native HTTP breadcrumbs for URLs with a query string - #6881

Merged
antonis merged 4 commits into
mainfrom
antonis/fix-http-breadcrumb-dedup-query
Oct 15, 2026
Merged

antonis merged 4 commits into
mainfrom
antonis/fix-http-breadcrumb-dedup-query

Conversation

@antonis

@antonis antonis commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

📢 Type of change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring

📜 Description

URLs are now normalized before comparing:

  • JS URL: the query and fragment are cut off while the URL is still encoded. Then credentials are removed, the scheme and host are lowercased, the URL is decoded, and a trailing slash is dropped.
  • Native URL: credentials are removed, the scheme and host are lowercased, and the URL is decoded. It is not cut at ?, because after decoding a ? may belong to the path.
  • Match: the native URL must equal the JS URL, or be the JS URL followed by /, ?… or /?…. Identical raw URLs still always match.

💡 Motivation and Context

Fixes #6872

💚 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

antonis and others added 2 commits October 13, 2026 10:45
…string

The native iOS breadcrumb's url is sanitized (query moved to http.query or
filtered, percent-decoded, credentials replaced), so the exact url match
against the raw JS xhr/fetch url failed. Compare normalized urls instead and
ignore the query.

Fixes #6872

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 13, 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(core): Deduplicate native HTTP breadcrumbs for URLs with a query string by antonis in #6881
  • fix(android): Include CPU and memory measurements in Android profiles by antonis in #6891
  • chore(deps): update Cocoa SDK to v9.30.2 by github-actions in #6888
  • test(e2e): iOS crash-handler screenshot no-freeze regression check by antonis in #6839
  • fix(replay): Attach Session Replay buffer to user feedback by antonis in #6870
  • chore(deps): update Android SDK to v8.61.0 by github-actions in #6889
  • chore(deps): bump futureware-tech/simulator-action from 5 to 6 by dependabot in #6878
  • chore(deps): bump getsentry/craft from 2.33.1 to 2.34.1 by dependabot in #6880
  • chore(deps): bump actions/download-artifact from 8.0.1 to 8.0.2 by dependabot in #6879
  • chore(deps): bump ruby/setup-ruby from 1.327.0 to 1.328.0 by dependabot in #6877
  • chore(deps): bump the codeql-action group with 3 updates by dependabot in #6876
  • build(deps): Pin tinypool to patched 2.x to resolve prototype-pollution advisories by antonis in #6869
  • build(deps): Bump sharp, shell-quote and smol-toml to patched versions by antonis in #6868
  • fix(core): Do not mark sendDefaultPii as deprecated in React Native options by alwx in #6864
  • ci(ios): Archive the SwiftPM app to catch xcframework signature collisions by alwx in #6871
  • feat(core): Support applicationKey and moduleMetadata in Metro config by alwx in #6863
  • chore(deps): update JavaScript SDK to v10.76.2 by antonis in #6866
  • ci(core): Guard the "sideEffects": false contract with a lint check by antonis in #6836
  • chore(deps): bump nx from 22.7.7 to 22.7.12 by dependabot in #6857
  • chore(deps): bump compression from 1.7.5 to 1.8.2 by dependabot in #6856
  • chore(deps): bump postcss-selector-parser from 7.1.4 to 7.1.6 by dependabot in #6855
  • chore(deps): bump source-map-js from 1.2.1 to 1.2.2 by dependabot in #6854
  • chore(deps): bump proxy-addr from 2.0.7 to 2.0.8 by dependabot in #6853
  • chore(deps): bump handlebars from 4.7.9 to 4.7.10 by dependabot in #6862

Plus 1 more


🤖 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 2de5669. Configure here.

@antonis
antonis marked this pull request as ready for review October 13, 2026 09:49
nativeUrl === jsUrl ||
nativeUrl === `${jsUrl}/` ||
nativeUrl.startsWith(`${jsUrl}?`) ||
nativeUrl.startsWith(`${jsUrl}/?`)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is there a chance the question mark will be %3F?

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.

I think this is already covered since it is decoded at this point. Also checked with the the path has an encoded question mark test

/** Matches the native URL to the JS one, with or without a trailing slash or query. */
function isSameHttpUrl(nativeUrl: string, jsUrl: string): boolean {
return (
nativeUrl === jsUrl ||

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Isnt this check redundant since we do an equal check on line 139?

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.

Good question 👍 I rechecked and line 139 compares the raw URLs while this compares the normalised URLs

@lucas-zimerman

Copy link
Copy Markdown
Collaborator

Q: Isn't it possible to know if the request originated from the JavaScript layer? This way we could simply filter out these requests.

@antonis

antonis commented Oct 15, 2026

Copy link
Copy Markdown
Contributor Author

Q: Isn't it possible to know if the request originated from the JavaScript layer? This way we could simply filter out these requests.

I think this is feasible but would require marking on the JS side (similar to this).

@antonis antonis added the ready-to-merge Triggers the full CI test suite label Oct 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Android (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 454.67 ms 494.45 ms 39.78 ms
Size 50.56 MiB 56.63 MiB 6.07 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
0307fa4+dirty 454.16 ms 518.35 ms 64.18 ms
4953e94+dirty 442.02 ms 456.52 ms 14.50 ms
bc8f61e+dirty 442.98 ms 506.56 ms 63.58 ms
3817909+dirty 406.67 ms 416.58 ms 9.91 ms
4b87b12+dirty 421.82 ms 413.60 ms -8.22 ms
ef27341+dirty 412.94 ms 443.98 ms 31.04 ms
853723c+dirty 405.54 ms 440.08 ms 34.54 ms
2cac31b+dirty 440.48 ms 466.19 ms 25.71 ms
3b6e9f9+dirty 442.70 ms 486.44 ms 43.74 ms
4e0ba9c+dirty 452.84 ms 473.36 ms 20.52 ms

App size

Revision Plain With Sentry Diff
0307fa4+dirty 49.74 MiB 54.81 MiB 5.07 MiB
4953e94+dirty 43.75 MiB 48.08 MiB 4.33 MiB
bc8f61e+dirty 49.74 MiB 55.09 MiB 5.35 MiB
3817909+dirty 43.75 MiB 48.08 MiB 4.33 MiB
4b87b12+dirty 43.75 MiB 48.14 MiB 4.39 MiB
ef27341+dirty 48.30 MiB 53.54 MiB 5.24 MiB
853723c+dirty 48.30 MiB 53.58 MiB 5.28 MiB
2cac31b+dirty 49.74 MiB 55.37 MiB 5.63 MiB
3b6e9f9+dirty 48.30 MiB 53.54 MiB 5.23 MiB
4e0ba9c+dirty 48.30 MiB 53.49 MiB 5.19 MiB

@sentry

sentry Bot commented Oct 15, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

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

⚙️ sentry-react-native Build Distribution Settings

@github-actions

Copy link
Copy Markdown
Contributor

iOS (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 3861.23 ms 1224.23 ms -2637.00 ms
Size 5.15 MiB 6.96 MiB 1.81 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
b04af96+dirty 3818.92 ms 1219.76 ms -2599.16 ms
c0bc3e1+dirty 3862.00 ms 1228.59 ms -2633.41 ms
5a316ea+dirty 3820.11 ms 1211.28 ms -2608.83 ms
09a902f+dirty 3835.67 ms 1217.11 ms -2618.57 ms
0a9e622+dirty 3835.87 ms 1221.07 ms -2614.80 ms
64630e5+dirty 3842.70 ms 1218.11 ms -2624.60 ms
032a8bd+dirty 3865.50 ms 1227.12 ms -2638.38 ms
0a147b2+dirty 3838.15 ms 1221.94 ms -2616.21 ms
68672fc+dirty 3841.58 ms 1228.89 ms -2612.69 ms
7ac3378+dirty 1213.37 ms 1218.15 ms 4.78 ms

App size

Revision Plain With Sentry Diff
b04af96+dirty 4.98 MiB 6.54 MiB 1.56 MiB
c0bc3e1+dirty 5.15 MiB 6.95 MiB 1.80 MiB
5a316ea+dirty 4.98 MiB 6.51 MiB 1.53 MiB
09a902f+dirty 4.98 MiB 6.46 MiB 1.49 MiB
0a9e622+dirty 4.98 MiB 6.51 MiB 1.53 MiB
64630e5+dirty 4.98 MiB 6.46 MiB 1.49 MiB
032a8bd+dirty 5.15 MiB 6.87 MiB 1.72 MiB
0a147b2+dirty 4.98 MiB 6.51 MiB 1.53 MiB
68672fc+dirty 5.15 MiB 6.71 MiB 1.55 MiB
7ac3378+dirty 3.38 MiB 4.76 MiB 1.38 MiB

@github-actions

Copy link
Copy Markdown
Contributor

iOS (new) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 3856.34 ms 1228.78 ms -2627.56 ms
Size 5.15 MiB 6.96 MiB 1.81 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
8448c07+dirty 3858.49 ms 1222.12 ms -2636.36 ms
580fb5c+dirty 3835.45 ms 1218.61 ms -2616.84 ms
44abcc2+dirty 3841.42 ms 1214.77 ms -2626.65 ms
c0bc3e1+dirty 3869.00 ms 1230.93 ms -2638.07 ms
d2eadf8+dirty 3841.53 ms 1216.15 ms -2625.39 ms
a216cb9+dirty 3853.25 ms 1224.77 ms -2628.48 ms
c004dae+dirty 3857.82 ms 1224.87 ms -2632.95 ms
ef27341+dirty 3835.20 ms 1212.23 ms -2622.97 ms
ad66da3+dirty 3855.02 ms 1213.43 ms -2641.59 ms
680f842+dirty 3874.00 ms 1229.35 ms -2644.65 ms

App size

Revision Plain With Sentry Diff
8448c07+dirty 4.98 MiB 6.55 MiB 1.57 MiB
580fb5c+dirty 4.98 MiB 6.46 MiB 1.48 MiB
44abcc2+dirty 4.98 MiB 6.55 MiB 1.57 MiB
c0bc3e1+dirty 5.15 MiB 6.95 MiB 1.80 MiB
d2eadf8+dirty 5.15 MiB 6.67 MiB 1.51 MiB
a216cb9+dirty 4.98 MiB 6.51 MiB 1.53 MiB
c004dae+dirty 5.15 MiB 6.67 MiB 1.51 MiB
ef27341+dirty 5.15 MiB 6.68 MiB 1.53 MiB
ad66da3+dirty 5.15 MiB 6.67 MiB 1.51 MiB
680f842+dirty 5.15 MiB 6.90 MiB 1.75 MiB

@github-actions

Copy link
Copy Markdown
Contributor

Android (new) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 453.48 ms 463.89 ms 10.41 ms
Size 50.56 MiB 56.63 MiB 6.07 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
7ff4d0f+dirty 403.38 ms 427.06 ms 23.68 ms
635676f+dirty 420.43 ms 428.23 ms 7.80 ms
ae37560+dirty 428.96 ms 456.86 ms 27.90 ms
df5d108+dirty 434.82 ms 447.39 ms 12.57 ms
0b5120f+dirty 413.75 ms 468.86 ms 55.11 ms
6acdf1d+dirty 417.34 ms 454.88 ms 37.54 ms
b47fb86+dirty 440.89 ms 500.73 ms 59.84 ms
4966363+dirty 415.67 ms 448.60 ms 32.93 ms
a0a3177+dirty 427.85 ms 473.94 ms 46.09 ms
c0bc3e1+dirty 570.52 ms 632.06 ms 61.54 ms

App size

Revision Plain With Sentry Diff
7ff4d0f+dirty 48.30 MiB 53.60 MiB 5.30 MiB
635676f+dirty 50.56 MiB 56.46 MiB 5.90 MiB
ae37560+dirty 48.30 MiB 53.60 MiB 5.29 MiB
df5d108+dirty 43.94 MiB 48.94 MiB 5.00 MiB
0b5120f+dirty 48.30 MiB 53.58 MiB 5.28 MiB
6acdf1d+dirty 49.74 MiB 55.09 MiB 5.34 MiB
b47fb86+dirty 50.56 MiB 56.59 MiB 6.03 MiB
4966363+dirty 48.30 MiB 53.54 MiB 5.24 MiB
a0a3177+dirty 49.74 MiB 55.37 MiB 5.63 MiB
c0bc3e1+dirty 50.56 MiB 56.62 MiB 6.06 MiB

@alwx alwx left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good (especially since you already checked what's written in comments by @lucas-zimerman)

@antonis antonis removed the ready-to-merge Triggers the full CI test suite label Oct 15, 2026
@antonis
antonis enabled auto-merge (squash) October 15, 2026 12:08
@github-actions

Copy link
Copy Markdown
Contributor
Fails
🚫 Pull request is not ready for merge, please add the "ready-to-merge" label to the pull request

Generated by 🚫 dangerJS against aaae161

@antonis
antonis merged commit 69b7ab2 into main Oct 15, 2026
50 of 68 checks passed
@antonis
antonis deleted the antonis/fix-http-breadcrumb-dedup-query branch October 15, 2026 12:11
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.

Native HTTP breadcrumb dedup never matches requests that have a query string

3 participants