Skip to content

fix(replay): Preserve segment ID after buffer-to-session conversion#5753

Merged
romtsn merged 7 commits into
mainfrom
rz/fix/replay-segment-id-normalization
Jul 13, 2026
Merged

fix(replay): Preserve segment ID after buffer-to-session conversion#5753
romtsn merged 7 commits into
mainfrom
rz/fix/replay-segment-id-normalization

Conversation

@romtsn

@romtsn romtsn commented Jul 10, 2026

Copy link
Copy Markdown
Member

📜 Description

After a buffer-to-session conversion (BufferCaptureStrategy.convert()), the replayType stays BUFFER (intentionally — it tells the backend this replay was triggered by an error). However, if the app crashes after the conversion and finalizePreviousReplay() recovers the last segment on next launch, ReplayCache.fromDisk() was normalizing the segment ID to 0 for all BUFFER-type replays.

This created a duplicate segment 0 with a late timestamp that overwrote the original segment 0 from the buffer flush, effectively losing the first segment of the replay.

The fix adds a persisted isFlushed flag that is set when the buffer is successfully flushed. fromDisk() now only normalizes the segment ID to 0 when the buffer was never flushed (i.e., no segments were ever sent to the server — the crash happened before any error triggered captureReplay).

💡 Motivation and Context

Customers reported the first segment of error-triggered replays sometimes being missing or showing content from the wrong time range. This was caused by finalizePreviousReplay creating a duplicate segment 0 that replaced the original.

💚 How did you test it?

  • Unit tests: updated existing test and added new test for the flushed case in ReplayCacheTest
  • Manual test on emulator: configured sample app for buffer-only replay, triggered captureException, waited for session segments, force-killed, relaunched — verified the finalized segment has the correct sequential ID (not 0)
  • Verified rrweb recording shows sequential segment IDs with proper timestamps

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the 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.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

🔮 Next steps

  • Investigate error-to-replay linkage issue (frozen transaction baggage doesn't pick up replayId set by captureReplay in buffer mode)

romtsn and others added 2 commits July 10, 2026 12:06
After a buffer-to-session conversion, the replay type stays BUFFER
but the segment counter reflects the real sequence. If the app
crashes and finalizePreviousReplay recovers the last segment,
fromDisk() was normalizing the segment ID to 0 for all BUFFER
replays, creating a duplicate segment 0 that overwrites the original.

Add a persisted isFlushed flag set when the buffer is successfully
flushed. fromDisk() now only normalizes to 0 when the buffer was
never flushed (no segments were ever sent to the server).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sentry

sentry Bot commented Jul 10, 2026

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.48.0 (1) release

⚙️ sentry-android Build Distribution Settings

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 329.48 ms 382.31 ms 52.83 ms
Size 0 B 0 B 0 B

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
6b019b7 319.84 ms 333.15 ms 13.31 ms
eb95ded 317.51 ms 369.08 ms 51.57 ms
319f256 317.53 ms 370.83 ms 53.29 ms
b3d8889 420.46 ms 453.71 ms 33.26 ms
6b019b7 403.90 ms 546.09 ms 142.19 ms
889ecea 367.58 ms 437.52 ms 69.94 ms
d15471f 303.49 ms 439.08 ms 135.59 ms
d364ace 384.53 ms 453.51 ms 68.98 ms
6ea4329 309.06 ms 353.48 ms 44.42 ms
c8125f3 383.82 ms 441.66 ms 57.84 ms

App size

Revision Plain With Sentry Diff
6b019b7 0 B 0 B 0 B
eb95ded 0 B 0 B 0 B
319f256 1.58 MiB 2.19 MiB 619.79 KiB
b3d8889 1.58 MiB 2.10 MiB 535.07 KiB
6b019b7 0 B 0 B 0 B
889ecea 1.58 MiB 2.11 MiB 539.75 KiB
d15471f 1.58 MiB 2.13 MiB 559.54 KiB
d364ace 1.58 MiB 2.11 MiB 539.75 KiB
6ea4329 1.58 MiB 2.29 MiB 719.82 KiB
c8125f3 1.58 MiB 2.10 MiB 532.32 KiB

Previous results on branch: rz/fix/replay-segment-id-normalization

Startup times

Revision Plain With Sentry Diff
39e4c55 352.43 ms 446.94 ms 94.51 ms
048e40b 322.47 ms 362.69 ms 40.22 ms
94ec28b 317.49 ms 407.84 ms 90.35 ms
a5d4b7b 413.28 ms 506.54 ms 93.26 ms

App size

Revision Plain With Sentry Diff
39e4c55 0 B 0 B 0 B
048e40b 0 B 0 B 0 B
94ec28b 0 B 0 B 0 B
a5d4b7b 0 B 0 B 0 B

Comment thread CHANGELOG.md Outdated
@romtsn romtsn marked this pull request as ready for review July 10, 2026 10:50
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
romtsn and others added 2 commits July 10, 2026 15:42
After buffer-to-session conversion, use the persisted segmentTimestamp
(which chains with previous segments) instead of the first frame
timestamp, avoiding gaps in the recovered segment timeline.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The gap from using first-frame timestamp vs persisted segmentTimestamp
is at most ~1s (1/frameRate) — negligible for crash recovery.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@romtsn romtsn enabled auto-merge (squash) July 13, 2026 19:29

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

@romtsn romtsn merged commit 31c558e into main Jul 13, 2026
71 checks passed
@romtsn romtsn deleted the rz/fix/replay-segment-id-normalization branch July 13, 2026 19:53
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