Repository navigation
Android: JS error screenshots ignore screenshot masking options (maskAllText / maskAllImages) #6900
Description
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
- Set attachScreenshot: true and screenshot: { maskAllText: true, maskAllImages: true } in Sentry.init.
- On Android, open a screen that shows text in plain components (and a TextInput with typed text).
- From JS, call Sentry.captureException(new Error('test')).
- 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:
- 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?
- 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?
- Is fail-closed (no screenshot) the behaviour you'd recommend when masking throws?
Metadata
Metadata
Assignees
Labels
Projects
- StatusShow more project fieldsNo status
Activity
linear-code commentedon Oct 16, 2026
RN-830
antonis commentedon Oct 16, 2026
Thank you for reporting 🙇
We will investigate this and iterate back.