Skip to content

Android: JS error screenshots ignore screenshot masking options (maskAllText / maskAllImages) #6900

Open

Description

@lisakikoda

What React Native libraries do you use?

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

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.30.0 (upgraded from 7.1.0; same behavior on both)

How does your development environment look like?

⬇  Place the `npx react-native@latest info` output here. ⬇
Expo SDK 53.0.27, react-native 0.79.6, Hermes, New Architecture on
sentry-android 8.60.0 (bundled by @sentry/react-native 8.30.0)
EAS development build; device: Motorola moto g power 5G (2024), Android 15



Sentry.init()

Sentry.init({
  dsn: '…',
  attachScreenshot: true,
  screenshot: { maskAllText: true, maskAllImages: true },
  // other options unrelated to screenshots omitted
});

Steps to Reproduce

  1. Set attachScreenshot: true and screenshot: { maskAllText: true, maskAllImages: true } in Sentry.init.
  2. On Android, open a screen that shows text in plain components (and a TextInput with typed text).
  3. From JS, call Sentry.captureException(new Error('test')).
  4. Open the event in Sentry → Attachments → screenshot.png.

Expected Result

Text and images in the error screenshot are masked, as documented ("Masking is enabled by default") and as configured via screenshot.maskAllText / maskAllImages.

Actual Result

On Android the screenshot is unmasked: all on-screen text and typed input is readable, with the options left at their defaults and with maskAllText / maskAllImages set to true explicitly. Session Replay masking works on the same screens.

This looks like the gap discussed in #6565 (closed for inactivity): screenshot.ts goes through NATIVE.captureScreenshot() → ScreenshotUtils.takeScreenshot, a raw capture, so the screenshot options never reach it. In that PR a maintainer suggested the fix belongs in sentry-java (a takeMaskedScreenshot for hybrid SDKs). As far as I can see, ScreenshotUtils in sentry-java 8.60.0 still has no masked variant (takeScreenshot and captureScreenshot are both raw).

A second, related mismatch: the docs and options.ts say screenshot.maskAllText / maskAllImages default to true, but on Android the native default is off. RNSentryStart only copies screenshot.* into the native options when the key is present, and SentryScreenshotOptions' constructor says "Default to NO masking until next major version". So even Android's native-crash screenshots (which do go through ScreenshotEventProcessor's masking) are unmasked unless the options are set explicitly.

We'd much rather keep masked screenshots than turn them off. We're considering a local patch-package of RNSentryModuleImpl.takeScreenshotOnUiThread that mirrors ScreenshotEventProcessor's masking (capture -> ViewHierarchyNode traverse -> MaskRenderer), keeping the getMaskViewClasses().isEmpty() gate and a replay-module availability check, and returning no screenshot if masking fails. Before we ship that:

  1. Is a masked screenshot for hybrid SDKs (e.g. a takeMaskedScreenshot in sentry-java, or reopening fix(android): apply screenshot masking in captureScreenshot() #6565) planned or in progress?
  2. Are there known dangers with running that pipeline from the hybrid path: UI-thread cost, New Architecture / Fabric views, anything ScreenshotEventProcessor relies on that the RN path doesn't set up?
  3. Is fail-closed (no screenshot) the behaviour you'd recommend when masking throws?

Activity

  1. linear-code commented on Oct 16, 2026

    @linear-code
  2. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Oct 16, 2026
  3. antonis commented on Oct 16, 2026

    @antonis
    Contributor

    Thank you for reporting 🙇
    We will investigate this and iterate back.

  4. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Oct 16, 2026
  5. self-assigned this
    on Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions