Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

JS exceptions often lack debug_meta on Hermes; profiling path already has a robust Debug ID lookup #6480

Copy link
Copy link

Description

@deadlinecode
Issue body actions

Summary

On React Native + Hermes (including Expo OTA / expo export Hermes .hbc bundles), plain JS exception events often ship without debug_meta.images, even when:

  1. Metro has injected the Debug ID premodule (_sentryDebugIds / _sentryDebugIdIdentifier)
  2. The matching artifact bundle was uploaded with that Debug ID (sentry-expo-upload-sourcemaps / @sentry/expo-upload-sourcemaps, Release: None)

Profiling already solves this correctly via getDebugMetadata() in dist/js/profiling/debugid.js, which reads GLOBAL_OBJ._sentryDebugIds directly and stamps code_file as app:///index.android.bundle / app:///main.jsbundle. That helper is not wired into the exception event pipeline.

Why it matters

Without debug_meta, backends fall back to release + filename matching. Expo/RN rewrites every JS frame to the same canonical filename (app:///index.android.bundle / app:///main.jsbundle) via RewriteFrames. OTA updates keep the native release, so symbolication can apply the native build’s Hermes map to OTA bytecode → wrong files/lines.

This is especially painful on Sentry-compatible self-hosts, but the missing debug_meta is an SDK-side gap regardless of backend.

Observed with @sentry/react-native 8.19.0, Expo Router, Hermes, OTA via artifact bundles.

Root cause (SDK)

Exception events rely on @sentry/core prepareEventapplyDebugIdsgetFilenameToDebugIdMap:

  1. Take the single key in _sentryDebugIds (the Error().stack string captured when the Debug ID premodule ran)
  2. Re-parse that stack with the generic stack parser
  3. Require an exact filename string match against exception frames

That path is fragile for Hermes top-level/premodule stacks. If the reparse yields no usable filename (or a different shape than real exception frames), filenameDebugIdMap is empty → applyDebugMeta no-ops → no debug_meta on the event.

By contrast, profiling:

// profiling/debugid.ts (conceptually)
const debugId = Object.values(GLOBAL_OBJ._sentryDebugIds)[0]
return [{ type: 'sourcemap', code_file: DEFAULT_BUNDLE_NAME, debug_id: debugId }]

No stack reparse. One bundle, one Debug ID, fixed code_file.

Suggested fix

Reuse the profiling approach for all events:

  • Extract / share getDebugMetadata() outside profiling
  • Add a default integration (or extend an existing one) that stamps event.debug_meta.images from _sentryDebugIds (+ _sentryDebugIdIdentifier fallback) using ANDROID_DEFAULT_BUNDLE_NAME / IOS_DEFAULT_BUNDLE_NAME
  • Keep it idempotent if core applyDebugIds already succeeded

This matches how RN actually works (single Hermes bundle per platform) and makes Expo OTA Debug ID matching reliable without release/dist workarounds.

Reproduction sketch

  1. Expo app with getSentryExpoConfig + @sentry/react-native/expo plugin
  2. Publish an OTA / expo export Hermes bundle; upload with npx @sentry/expo-upload-sourcemaps dist (artifact bundle, Debug ID in upload report)
  3. On a device running that OTA (Updates.isEmbeddedLaunch === false), Sentry.captureException(new Error('probe'))
  4. Inspect event JSON: debug_meta often missing; release still native (*.androidapp@x.y.z+build); frames use app:///index.android.bundle

Workaround we use today

App-level Sentry.addEventProcessor that mirrors profiling’s getDebugMetadata() and attaches debug_meta.images before send. Happy to upstream that if maintainers agree on the approach.

Related

  • Expo docs assume Debug ID path “just works” after sentry-expo-upload-sourcemaps (Using Sentry)
  • Metro Debug ID injection is fine; upload Debug IDs match; the break is event emission
Reactions are currently unavailable

Metadata

Metadata

Assignees

Labels

BugErrorsExpoIssues related to Sentry React Native Expo supportIssues related to Sentry React Native Expo supportReact-Native

Projects

Status
No status
Show more project fields

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

Morty Proxy This is a proxified and sanitized view of the page, visit original site.