Skip to content

fix(replay): Attach Session Replay buffer to user feedback - #6870

Draft
antonis wants to merge 14 commits into
mainfrom
fix/feedback-form-replay-buffer
Draft

antonis wants to merge 14 commits into
mainfrom
fix/feedback-form-replay-buffer

Conversation

@antonis

@antonis antonis commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

📢 Type of change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring

📜 Description

This PR wires the RN feedback form into the same replay handshake the web widget and the native iOS form already use

💡 Motivation and Context

Fixes #6867

💚 How did you test it?

📝 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 3 commits October 12, 2026 11:51
Flush the on-error Session Replay buffer when the feedback widget opens and
link it to the feedback event on submit, mirroring the web widget and the
native iOS form. Previously feedback from the RN form never carried a replay
unless replay happened to be in session mode.

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

github-actions Bot commented Oct 12, 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(replay): Attach Session Replay buffer to user feedback by antonis in #6870
  • 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
  • chore(deps): update Wizard to v8.0.1 by github-actions in #6852

🤖 This preview updates automatically when you update the PR.

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

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Android (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 429.35 ms 443.51 ms 14.16 ms
Size 50.56 MiB 56.62 MiB 6.06 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
44c8b3f+dirty 414.20 ms 457.28 ms 43.08 ms
6e4ddc2+dirty 449.09 ms 473.63 ms 24.55 ms
8cae3b5+dirty 545.72 ms 577.88 ms 32.16 ms
a0a3177+dirty 441.27 ms 499.86 ms 58.59 ms
20fbd51+dirty 487.89 ms 535.60 ms 47.71 ms
9ad4522+dirty 420.73 ms 444.18 ms 23.45 ms
a9df5ce+dirty 418.40 ms 452.38 ms 33.98 ms
bbb8d67+dirty 495.63 ms 525.50 ms 29.87 ms
ca9d079+dirty 411.29 ms 455.12 ms 43.83 ms
3d31fcf+dirty 451.00 ms 499.08 ms 48.08 ms

App size

Revision Plain With Sentry Diff
44c8b3f+dirty 48.30 MiB 53.46 MiB 5.15 MiB
6e4ddc2+dirty 50.56 MiB 56.59 MiB 6.03 MiB
8cae3b5+dirty 50.56 MiB 56.59 MiB 6.03 MiB
a0a3177+dirty 49.74 MiB 55.37 MiB 5.63 MiB
20fbd51+dirty 49.74 MiB 54.81 MiB 5.07 MiB
9ad4522+dirty 49.74 MiB 55.38 MiB 5.63 MiB
a9df5ce+dirty 49.74 MiB 55.36 MiB 5.62 MiB
bbb8d67+dirty 49.74 MiB 55.36 MiB 5.62 MiB
ca9d079+dirty 48.30 MiB 53.58 MiB 5.28 MiB
3d31fcf+dirty 49.74 MiB 55.38 MiB 5.63 MiB

Previous results on branch: fix/feedback-form-replay-buffer

Startup times

Revision Plain With Sentry Diff
e99faa0+dirty 547.00 ms 601.35 ms 54.35 ms
3aeaddf+dirty 458.53 ms 543.27 ms 84.73 ms

App size

Revision Plain With Sentry Diff
e99faa0+dirty 50.56 MiB 56.62 MiB 6.06 MiB
3aeaddf+dirty 50.56 MiB 56.62 MiB 6.06 MiB

@sentry

sentry Bot commented Oct 12, 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

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

iOS (legacy) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 3864.74 ms 1239.70 ms -2625.05 ms
Size 5.15 MiB 6.95 MiB 1.80 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
8508235+dirty 3859.02 ms 1230.11 ms -2628.91 ms
5920f6b+dirty 3866.23 ms 1239.47 ms -2626.76 ms
5c1e987+dirty 1204.30 ms 1222.15 ms 17.85 ms
2c735cc+dirty 1229.67 ms 1221.50 ms -8.17 ms
5569641+dirty 3839.22 ms 1231.30 ms -2607.91 ms
7ac3378+dirty 1213.37 ms 1218.15 ms 4.78 ms
40c9884+dirty 3837.72 ms 1226.61 ms -2611.11 ms
5a21b51+dirty 3823.11 ms 1214.46 ms -2608.65 ms
ecf47a2+dirty 3835.20 ms 1222.43 ms -2612.77 ms
92aa6d3+dirty 3845.44 ms 1229.26 ms -2616.18 ms

App size

Revision Plain With Sentry Diff
8508235+dirty 5.15 MiB 6.95 MiB 1.80 MiB
5920f6b+dirty 5.15 MiB 6.93 MiB 1.78 MiB
5c1e987+dirty 3.38 MiB 4.73 MiB 1.35 MiB
2c735cc+dirty 3.38 MiB 4.74 MiB 1.35 MiB
5569641+dirty 5.15 MiB 6.67 MiB 1.51 MiB
7ac3378+dirty 3.38 MiB 4.76 MiB 1.38 MiB
40c9884+dirty 4.98 MiB 6.51 MiB 1.53 MiB
5a21b51+dirty 5.15 MiB 6.67 MiB 1.51 MiB
ecf47a2+dirty 4.98 MiB 6.46 MiB 1.49 MiB
92aa6d3+dirty 5.15 MiB 6.93 MiB 1.78 MiB

Previous results on branch: fix/feedback-form-replay-buffer

Startup times

Revision Plain With Sentry Diff
e99faa0+dirty 3861.67 ms 1236.60 ms -2625.07 ms
3aeaddf+dirty 3867.88 ms 1241.45 ms -2626.42 ms

App size

Revision Plain With Sentry Diff
e99faa0+dirty 5.15 MiB 6.95 MiB 1.80 MiB
3aeaddf+dirty 5.15 MiB 6.95 MiB 1.80 MiB

Comment thread packages/core/src/js/replay/mobilereplay.ts
Comment thread packages/core/src/js/replay/mobilereplay.ts
Comment thread packages/core/src/js/replay/mobilereplay.ts Outdated
@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

iOS (new) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 3870.35 ms 1232.63 ms -2637.72 ms
Size 5.15 MiB 6.95 MiB 1.80 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
8508235+dirty 3859.19 ms 1225.73 ms -2633.46 ms
5fe1c6c+dirty 1201.36 ms 1209.15 ms 7.78 ms
09a902f+dirty 3847.65 ms 1221.31 ms -2626.34 ms
88735e9+dirty 3837.80 ms 1216.39 ms -2621.41 ms
7b7b4fa+dirty 3866.52 ms 1230.35 ms -2636.17 ms
5a23c47+dirty 3843.54 ms 1226.05 ms -2617.50 ms
3e3142c+dirty 3831.04 ms 1206.04 ms -2625.00 ms
680f842+dirty 3874.00 ms 1229.35 ms -2644.65 ms
f3215d3+dirty 3846.08 ms 1231.85 ms -2614.23 ms
5a010b7+dirty 3856.76 ms 1232.65 ms -2624.11 ms

App size

Revision Plain With Sentry Diff
8508235+dirty 5.15 MiB 6.95 MiB 1.80 MiB
5fe1c6c+dirty 3.38 MiB 4.77 MiB 1.39 MiB
09a902f+dirty 4.98 MiB 6.46 MiB 1.49 MiB
88735e9+dirty 4.98 MiB 6.46 MiB 1.49 MiB
7b7b4fa+dirty 5.15 MiB 6.94 MiB 1.79 MiB
5a23c47+dirty 4.98 MiB 6.46 MiB 1.49 MiB
3e3142c+dirty 5.08 MiB 6.56 MiB 1.48 MiB
680f842+dirty 5.15 MiB 6.90 MiB 1.75 MiB
f3215d3+dirty 5.15 MiB 6.67 MiB 1.52 MiB
5a010b7+dirty 5.15 MiB 6.69 MiB 1.54 MiB

Previous results on branch: fix/feedback-form-replay-buffer

Startup times

Revision Plain With Sentry Diff
e99faa0+dirty 3854.78 ms 1204.67 ms -2650.11 ms
3aeaddf+dirty 3870.58 ms 1242.93 ms -2627.65 ms

App size

Revision Plain With Sentry Diff
e99faa0+dirty 5.15 MiB 6.95 MiB 1.80 MiB
3aeaddf+dirty 5.15 MiB 6.95 MiB 1.80 MiB

@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Android (new) Performance metrics 🚀

  Plain With Sentry Diff
Startup time 492.82 ms 545.90 ms 53.08 ms
Size 50.56 MiB 56.62 MiB 6.06 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
bbb8d67+dirty 465.41 ms 502.40 ms 36.99 ms
6e4ddc2+dirty 452.40 ms 468.71 ms 16.31 ms
3b6e9f9+dirty 442.39 ms 486.44 ms 44.05 ms
5125c43+dirty 409.52 ms 451.00 ms 41.48 ms
038a6d7+dirty 499.02 ms 527.68 ms 28.66 ms
6acdf1d+dirty 417.34 ms 454.88 ms 37.54 ms
8cae3b5+dirty 438.79 ms 464.50 ms 25.71 ms
5b7e8a7+dirty 601.58 ms 634.98 ms 33.40 ms
44c8b3f+dirty 492.13 ms 563.47 ms 71.34 ms
3ce5254+dirty 373.90 ms 427.84 ms 53.94 ms

App size

Revision Plain With Sentry Diff
bbb8d67+dirty 49.74 MiB 55.36 MiB 5.62 MiB
6e4ddc2+dirty 50.56 MiB 56.59 MiB 6.03 MiB
3b6e9f9+dirty 48.30 MiB 53.54 MiB 5.23 MiB
5125c43+dirty 48.30 MiB 53.54 MiB 5.24 MiB
038a6d7+dirty 48.30 MiB 53.60 MiB 5.30 MiB
6acdf1d+dirty 49.74 MiB 55.09 MiB 5.34 MiB
8cae3b5+dirty 50.56 MiB 56.59 MiB 6.03 MiB
5b7e8a7+dirty 48.30 MiB 53.58 MiB 5.28 MiB
44c8b3f+dirty 48.30 MiB 53.46 MiB 5.15 MiB
3ce5254+dirty 43.94 MiB 48.98 MiB 5.04 MiB

Previous results on branch: fix/feedback-form-replay-buffer

Startup times

Revision Plain With Sentry Diff
e99faa0+dirty 432.77 ms 461.45 ms 28.68 ms
3aeaddf+dirty 428.46 ms 492.35 ms 63.89 ms

App size

Revision Plain With Sentry Diff
e99faa0+dirty 50.56 MiB 56.62 MiB 6.06 MiB
3aeaddf+dirty 50.56 MiB 56.62 MiB 6.06 MiB

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

Stale Bugbot comment from a previous run.

Comment thread packages/core/src/js/replay/mobilereplay.ts Outdated
Comment thread packages/core/src/js/replay/mobilereplay.ts
…cel, and sampling miss

Capture the recording id synchronously when the feedback widget opens (so a late
flush resolution can't revive a consumed id), and route by feedback source so a
cancelled widget never leaks its id to a later captureFeedback. On a sampling miss
the id is linked optimistically, consistent with the error path.

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.

Stale Bugbot comment from a previous run.

Comment thread packages/core/src/js/replay/mobilereplay.ts
…e remount

Use the result of the widget-open flush (null on a sampling miss => no link) instead
of an eagerly-read id, and start a fresh flush per open so a form remount (screenshot
flow) supersedes the previous one instead of overwriting the captured id.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread packages/core/src/js/replay/mobilereplay.ts Outdated
Comment thread packages/core/test/feedback/FeedbackForm.test.tsx
antonis and others added 2 commits October 12, 2026 14:21
…che writes

Read the buffer id before the widget-open flush and use it as the fallback when a
submit precedes the flush resolving (the controller id can already be a new buffer
after capture on Android), and stop a superseded/consumed feedback flush from
overwriting the shared replay-id cache used by DSCs and metrics.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread packages/core/src/js/replay/mobilereplay.ts
antonis and others added 3 commits October 12, 2026 14:55
…lush

captureReplay can change the native replay identity, so drop the cached id when the
widget-open flush settles (the next DSC/metric re-reads the current one) rather than
leaving the stale pre-flush id in the cache.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
End the capture chain with a rejection handler (no trailing `.then`) so the
no-floating-promises lint passes; the settle step runs in both branches.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread packages/core/src/js/replay/mobilereplay.ts Outdated
…sh too

The direct captureFeedback path flushes the buffer but left the cached id stale;
invalidate it on settle like the widget flush, so DSCs and metrics re-read the
current native id instead of the pre-flush one.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread packages/core/src/js/replay/mobilereplay.ts
antonis and others added 2 commits October 12, 2026 16:38
…y id

Guard the openFeedbackWidget and beforeSendFeedback listeners so a synchronous
bridge throw from getCurrentReplayId/captureReplay cannot propagate out of the
widget's componentDidMount or abort feedback capture, matching the beforeSend
wrapper. Also carry forward a replay id an earlier widget open already uploaded
so a remount whose own flush uploads nothing links it instead of discarding it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A remount while the first open's captureReplay is still pending previously
replaced the in-flight flush with a fresh one, discarding the pending upload so
submit could link nothing. Keep the in-flight flush and only start a new one
once the previous has settled, alongside the existing carry-forward of a
completed upload.

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.

✅ 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 6bb871e. Configure here.

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.

Feedback form never attaches the on-error replay buffer

1 participant