fix(core): Attach debug_meta to Hermes JS error events via Debug ID lookup - #6545
Draft
antonis wants to merge 2 commits into
Draft
fix(core): Attach debug_meta to Hermes JS error events via Debug ID lookup#6545antonis wants to merge 2 commits into
antonis wants to merge 2 commits into
Conversation
…ookup Error events relied on the core applyDebugIds path, which re-parses the Metro-injected premodule Error().stack and requires an exact filename match against the exception frames. That match is fragile for Hermes premodule stacks, so events frequently shipped without debug_meta and symbolication fell back to release + filename matching (broken for Expo OTA updates that keep the native release). Add a debugMetaIntegration that reuses profiling's direct Debug ID lookup (getDebugMetadata) to stamp debug_meta.images for error events. It backs off when core already matched the stack (frame.debug_id set) to avoid emitting a duplicate image, and dedupes defensively. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
Semver Impact of This PR⚪ None (no version bump detected) 📋 Changelog PreviewThis is how your changes will appear in the changelog.
🤖 This preview updates automatically when you update the PR. |
antonis
force-pushed
the
fix/6480-debug-meta-hermes
branch
from
July 30, 2026 15:51
073c8a0 to
f40d5e0
Compare
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
Author
|
@sentry review |
There was a problem hiding this comment.
✅ 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 3b10f42. Configure here.
📲 Install BuildsAndroid
|
Contributor
iOS (legacy) Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 2cac31b+dirty | 3886.27 ms | 1230.85 ms | -2655.42 ms |
| 244f6e8+dirty | 3833.36 ms | 1212.96 ms | -2620.41 ms |
| 61cc206+dirty | 3849.70 ms | 1230.33 ms | -2619.38 ms |
| 04207c4+dirty | 1191.27 ms | 1189.78 ms | -1.48 ms |
| acd838e+dirty | 3849.78 ms | 1230.00 ms | -2619.78 ms |
| fa21fca+dirty | 3840.43 ms | 1224.42 ms | -2616.02 ms |
| 0d9949d+dirty | 1211.38 ms | 1219.67 ms | 8.29 ms |
| bc8f61e+dirty | 3819.00 ms | 1220.22 ms | -2598.78 ms |
| ca9d079+dirty | 3835.63 ms | 1218.68 ms | -2616.95 ms |
| 5a316ea+dirty | 3820.11 ms | 1211.28 ms | -2608.83 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 2cac31b+dirty | 4.98 MiB | 6.55 MiB | 1.58 MiB |
| 244f6e8+dirty | 4.98 MiB | 6.56 MiB | 1.58 MiB |
| 61cc206+dirty | 4.98 MiB | 6.55 MiB | 1.57 MiB |
| 04207c4+dirty | 3.38 MiB | 4.76 MiB | 1.38 MiB |
| acd838e+dirty | 5.15 MiB | 6.70 MiB | 1.55 MiB |
| fa21fca+dirty | 4.98 MiB | 6.55 MiB | 1.57 MiB |
| 0d9949d+dirty | 3.38 MiB | 4.76 MiB | 1.38 MiB |
| bc8f61e+dirty | 4.98 MiB | 6.47 MiB | 1.49 MiB |
| ca9d079+dirty | 5.15 MiB | 6.69 MiB | 1.53 MiB |
| 5a316ea+dirty | 4.98 MiB | 6.51 MiB | 1.53 MiB |
Contributor
iOS (new) Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 2cac31b+dirty | 3854.43 ms | 1212.35 ms | -2642.08 ms |
| 244f6e8+dirty | 3825.51 ms | 1217.76 ms | -2607.75 ms |
| 9474ead+dirty | 3823.33 ms | 1208.31 ms | -2615.03 ms |
| 44c8b3f+dirty | 3849.24 ms | 1209.94 ms | -2639.31 ms |
| 61cc206+dirty | 3822.60 ms | 1206.17 ms | -2616.43 ms |
| acd838e+dirty | 3835.94 ms | 1215.87 ms | -2620.07 ms |
| b0d3373+dirty | 3842.49 ms | 1218.49 ms | -2624.00 ms |
| fa21fca+dirty | 3845.12 ms | 1215.89 ms | -2629.24 ms |
| 0d9949d+dirty | 1203.94 ms | 1202.27 ms | -1.67 ms |
| a5d243c+dirty | 3827.92 ms | 1220.10 ms | -2607.81 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 2cac31b+dirty | 4.98 MiB | 6.55 MiB | 1.58 MiB |
| 244f6e8+dirty | 4.98 MiB | 6.56 MiB | 1.58 MiB |
| 9474ead+dirty | 5.15 MiB | 6.71 MiB | 1.55 MiB |
| 44c8b3f+dirty | 5.15 MiB | 6.66 MiB | 1.51 MiB |
| 61cc206+dirty | 4.98 MiB | 6.55 MiB | 1.57 MiB |
| acd838e+dirty | 5.15 MiB | 6.70 MiB | 1.55 MiB |
| b0d3373+dirty | 5.15 MiB | 6.68 MiB | 1.53 MiB |
| fa21fca+dirty | 4.98 MiB | 6.55 MiB | 1.57 MiB |
| 0d9949d+dirty | 3.38 MiB | 4.76 MiB | 1.38 MiB |
| a5d243c+dirty | 5.15 MiB | 6.68 MiB | 1.53 MiB |
Contributor
Android (legacy) Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 1d3572b+dirty | 435.35 ms | 487.32 ms | 51.96 ms |
| d2eadf8+dirty | 414.64 ms | 454.56 ms | 39.92 ms |
| 7d8c8bd+dirty | 417.45 ms | 462.10 ms | 44.65 ms |
| bf168a4+dirty | 418.21 ms | 489.74 ms | 71.53 ms |
| 890d145+dirty | 504.54 ms | 491.55 ms | -12.99 ms |
| ad66da3+dirty | 468.46 ms | 533.56 ms | 65.10 ms |
| 15d4514+dirty | 406.77 ms | 428.06 ms | 21.29 ms |
| a0a3177+dirty | 441.27 ms | 499.86 ms | 58.59 ms |
| 6acdf1d+dirty | 513.58 ms | 608.31 ms | 94.72 ms |
| 038a6d7+dirty | 524.82 ms | 531.92 ms | 7.10 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 1d3572b+dirty | 49.74 MiB | 55.38 MiB | 5.63 MiB |
| d2eadf8+dirty | 48.30 MiB | 53.48 MiB | 5.18 MiB |
| 7d8c8bd+dirty | 48.30 MiB | 53.54 MiB | 5.23 MiB |
| bf168a4+dirty | 49.74 MiB | 55.09 MiB | 5.35 MiB |
| 890d145+dirty | 43.75 MiB | 48.14 MiB | 4.39 MiB |
| ad66da3+dirty | 48.30 MiB | 53.49 MiB | 5.19 MiB |
| 15d4514+dirty | 48.30 MiB | 53.60 MiB | 5.30 MiB |
| a0a3177+dirty | 49.74 MiB | 55.37 MiB | 5.63 MiB |
| 6acdf1d+dirty | 49.74 MiB | 55.09 MiB | 5.34 MiB |
| 038a6d7+dirty | 48.30 MiB | 53.60 MiB | 5.30 MiB |
Contributor
Android (new) Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 1d3572b+dirty | 444.48 ms | 478.42 ms | 33.94 ms |
| 6177334+dirty | 404.80 ms | 456.74 ms | 51.94 ms |
| 5a23c47+dirty | 406.83 ms | 451.47 ms | 44.64 ms |
| a3265b6+dirty | 410.96 ms | 444.76 ms | 33.80 ms |
| bf168a4+dirty | 430.60 ms | 459.31 ms | 28.71 ms |
| ca9d079+dirty | 460.67 ms | 512.54 ms | 51.87 ms |
| ef27341+dirty | 519.02 ms | 553.42 ms | 34.40 ms |
| 23598c3+dirty | 371.92 ms | 420.65 ms | 48.74 ms |
| 7d6fd3a+dirty | 435.06 ms | 458.78 ms | 23.72 ms |
| a50b33d+dirty | 353.21 ms | 398.48 ms | 45.27 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 1d3572b+dirty | 49.74 MiB | 55.38 MiB | 5.63 MiB |
| 6177334+dirty | 48.30 MiB | 53.54 MiB | 5.23 MiB |
| 5a23c47+dirty | 49.74 MiB | 54.82 MiB | 5.07 MiB |
| a3265b6+dirty | 48.30 MiB | 53.58 MiB | 5.28 MiB |
| bf168a4+dirty | 49.74 MiB | 55.09 MiB | 5.35 MiB |
| ca9d079+dirty | 48.30 MiB | 53.58 MiB | 5.28 MiB |
| ef27341+dirty | 48.30 MiB | 53.54 MiB | 5.24 MiB |
| 23598c3+dirty | 43.94 MiB | 49.02 MiB | 5.08 MiB |
| 7d6fd3a+dirty | 43.94 MiB | 49.00 MiB | 5.06 MiB |
| a50b33d+dirty | 43.94 MiB | 48.94 MiB | 5.00 MiB |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📢 Type of change
📜 Description
On React Native + Hermes (including Expo OTA /
expo exportHermes bundles), plain JS exception events often ship withoutdebug_meta.images, even when Metro injected the Debug ID premodule (_sentryDebugIds) and the matching artifact bundle was uploaded with that Debug ID.The core
prepareEventpipeline attempts this viaapplyDebugIds→applyDebugMeta, but that path re-parses the premoduleError().stackand requires an exact filename match against the exception frames. That match is fragile for Hermes premodule stacks, sofilenameDebugIdMapends up empty and nodebug_metais attached.Profiling already solves the same problem robustly via
getDebugMetadata()(profiling/debugid.ts): it reads_sentryDebugIdsdirectly and stamps a singlesourcemapimage with the canonical bundlecode_file(app:///index.android.bundle/app:///main.jsbundle) — no stack reparse. That helper was not wired into the error event pipeline.This PR adds a default
debugMetaIntegrationthat reusesgetDebugMetadata()to stampdebug_meta.imageson error events. Key details:event.type === undefined) — transactions, profiles and other event types are untouched.applyDebugIds(setsframe.debug_id) before event processors andapplyDebugMeta(stamps images) after them. The integration detects a successful core match viaframe.debug_idand backs off, so core's own stamp is not duplicated. When core fails to match (the bug case), the integration fills the gap.debug_id, and preserves unrelated pre-existing images (e.g. native images added bynativeLinkedErrors).createReactNativeRewriteFrames()so the canonical bundle filename is already in place.💡 Motivation and Context
Without
debug_meta, backends fall back to release + filename matching. RN/Expo rewrites every JS frame to the same canonical filename, and OTA updates keep the native release, so the native build's Hermes map can be applied to OTA bytecode → wrong files/lines. The missingdebug_metais an SDK-side gap regardless of backend.Fixes #6480
💚 How did you test it?
test/integrations/debugmeta.test.tscovering: stamping on error events, no-op when no Debug ID, skipping non-error events, backing off when core matched, and preserving pre-existing images.prepareEventordering (applyDebugIds→ event processor →applyDebugMeta) and assert exactly one image results whether core succeeds or fails — guarding against a duplicate-image regression.debugMetaIntegration.📝 Checklist
sendDefaultPIIis enabled.🔮 Next steps
debugMetaIntegration) — the mechanism is RN/Hermes-specific (single bundle per platform); a more specific name could be used if preferred.🤖 Generated with Claude Code