Skip to content

Native crashes on Android leaves app on a white screen #5973

@joarkosberg

Description

@joarkosberg

What React Native libraries do you use?

Expo (mobile only), Hermes, React Navigation, RN New Architecture

Are you using sentry.io or on-premise?

sentry.io (SaS)

Are you using any other error monitoring solution alongside Sentry?

No

Other Error Monitoring Solution Name

No response

@sentry/react-native SDK Version

8.7.0

How does your development environment look like?

System:
  OS: macOS 26.4
  CPU: (14) arm64 Apple M3 Max
  Memory: 268.95 MB / 36.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 24.14.1
    path: /opt/homebrew/opt/node@24/bin/node
  Yarn:
    version: 3.6.4
    path: ~/.yarn/bin/yarn
  npm:
    version: 11.11.0
    path: /opt/homebrew/opt/node@24/bin/npm
  Watchman: Not Found
Managers:
  CocoaPods:
    version: 1.16.2
    path: /opt/homebrew/lib/ruby/gems/3.4.0/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 25.4
      - iOS 26.4
      - macOS 26.4
      - tvOS 26.4
      - visionOS 26.4
      - watchOS 26.4
  Android SDK:
    API Levels:
      - "28"
      - "31"
      - "34"
      - "35"
      - "36"
      - "36"
    Build Tools:
      - 35.0.0
      - 36.0.0
      - 36.1.0
    System Images:
      - android-28 | Google ARM64-V8a Play ARM 64 v8a
      - android-36.1 | Google Play ARM 64 v8a
      - android-36 | Google Play ARM 64 v8a
      - android-36 | Pre-Release 16 KB Page Size Google Play ARM 64 v8a
    Android NDK: Not Found
IDEs:
  Android Studio: 2025.3 AI-253.31033.145.2533.15113396
  Xcode:
    version: 26.4/17E192
    path: /usr/bin/xcodebuild
Languages:
  Java:
    version: 17.0.18
    path: /usr/bin/javac
  Ruby:
    version: 3.4.9
    path: /opt/homebrew/opt/ruby@3.4/bin/ruby
npmPackages:
  "@react-native-community/cli":
    installed: 20.1.0
    wanted: 20.1.0
  react:
    installed: 19.2.3
    wanted: 19.2.3
  react-native:
    installed: 0.84.1
    wanted: 0.84.1
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: Not found
  newArchEnabled: false


Sentry.init()

Sentry.init({
  beforeSend: (event: Sentry.ErrorEvent) => {
    logWithoutTracing('Event beforeSend:', event.event_id);
    return event;
  },
  beforeSendTransaction(event: Sentry.TransactionEvent) {
    logWithoutTracing('Transaction beforeSend:', event.event_id);
    return event;
  },
  beforeSendMetric(metric: Sentry.Metric) {
    logWithoutTracing('Metric beforeSend:', metric.name, metric.value);
    return metric;
  },
  // This will be called with a boolean `didCallNativeInit` when the native SDK has been contacted.
  onReady: ({ didCallNativeInit }) => {
    logWithoutTracing(
      'onReady called with didCallNativeInit:',
      didCallNativeInit,
    );
  },
  _experiments: {
    enableUnhandledCPPExceptionsV2: true,
  },
  logsOrigin: 'all',
  enableLogs: true,
  beforeSendLog: log => {
    return log;
  },
  enableUserInteractionTracing: true,
  integrations(integrations) {
    integrations.push(
      reactNavigationIntegration,
      Sentry.reactNativeTracingIntegration({
        // The time to wait in ms until the transaction will be finished, For testing, default is 1000 ms
        idleTimeoutMs: 5_000,
      }),
      Sentry.httpClientIntegration({
        // These options are effective only in JS.
        // This array can contain tuples of `[begin, end]` (both inclusive),
        // Single status codes, or a combinations of both.
        // default: [[500, 599]]
        failedRequestStatusCodes: [[400, 599]],
        // This array can contain Regexes or strings, or combinations of both.
        // default: [/.*/]
        failedRequestTargets: [/.*/],
      }),
      Sentry.mobileReplayIntegration({
        maskAllImages: true,
        maskAllVectors: true,
        maskAllText: true,
        enableViewRendererV2: true,
        screenshotStrategy: 'canvas', // if you have strict PII requirements
      }),
      Sentry.appStartIntegration({
        standalone: false,
      }),
      Sentry.reactNativeErrorHandlersIntegration({
        patchGlobalPromise:
          Platform.OS === 'ios' && isTurboModuleEnabled()
            ? // The global patch doesn't work on iOS with the New Architecture in this Sample app
              // In
              false
            : true,
      }),
      Sentry.feedbackIntegration({
        imagePicker: ImagePicker,
        enableScreenshot: true,
        enableTakeScreenshot: true,
        enableShakeToReport: true,
        styles: {
          submitButton: {
            backgroundColor: '#6a1b9a',
            paddingVertical: 15,
            borderRadius: 5,
            alignItems: 'center',
            marginBottom: 10,
          },
        },
        namePlaceholder: 'Fullname',
        buttonOptions: {
          styles: {
            triggerButton: {
              marginBottom: 75, // Place above the tab bar
            },
          },
        },
        screenshotButtonOptions: {
          styles: {
            triggerButton: {
              marginBottom: 75, // Place above the tab bar
            },
          },
        },
      }),
      Sentry.extraErrorDataIntegration(),
      sampleFeatureFlagsIntegration,
    );
    return integrations.filter(i => i.name !== 'Dedupe');
  },
  enableAutoSessionTracking: true,
  // For testing, session close when 5 seconds (instead of the default 30) in the background.
  sessionTrackingIntervalMillis: 30000,
  tracesSampleRate: 1.0,
  tracePropagationTargets: ['localhost', /^\//, /^https:\/\//, /^http:\/\//],
  attachStacktrace: true,
  // Attach screenshots to events.
  attachScreenshot: true,
  // Attach view hierarchy to events.
  attachViewHierarchy: true,
  // Enables capture failed requests in JS and native.
  enableCaptureFailedRequests: true,
  // Sets the `release` and `dist` on Sentry events. Make sure this matches EXACTLY with the values on your sourcemaps
  // otherwise they will not work.
  // release: 'myapp@1.2.3+1',
  // dist: `1`,
  profilesSampleRate: 1.0,
  replaysSessionSampleRate: 1.0,
  replaysOnErrorSampleRate: 1.0,
  ignoreErrors: ['should', /(.)*2(.)*/],
  replaysSessionQuality: 'medium', // default
  spotlight: false,
  // This should be disabled when manually initializing the native SDK
  // Note that options from JS are not passed to the native SDKs when initialized manually
  autoInitializeNativeSdk: shouldUseAutoStart(),
  enableMetrics: true,
});

Steps to Reproduce

Verified reproduction in the sentry sample app, so pasted info from there above ^ Also get it in my personal project where I first experienced it.

  1. Run sample app samples/react-native on Android
  2. Tap on NATIVE CRASH.
  3. Usually(not every time in the samples app) I am left on a white screen, with no where to go, instead of the app being closed.
    • In my own app the experience is that any unhandled error causes this white screen always. Where before it actually crashed the app fully closing it, so the app was not "stuck" on the white screen.

Expected Result

A full crash closing the app, so a user of the app is not stuck on a white screen and needs to close the app themself.

Actual Result

Uncaught crash causes a white screen, which only way to get rid of is to close the app yourself.
I started experiencing this when upgrading from 7.12.1 to 8.7.0 and adding the native inits.

Screen.Recording.2026-04-09.at.13.01.22.mov

Metadata

Metadata

Assignees

No one assigned
    No fields configured for issues without a type.

    Projects

    Status

    Waiting for: Product Owner

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions