OS
SDK
@sentry/react-native 8.19.0 (bug present since 8.14.0, when the TurboModuleContext integration was introduced; still present in 8.19.0)
React Native version
0.81.5 (Expo SDK 54, New Architecture, Hermes)
Steps to reproduce
Sentry.init({ dsn }) with default integrations (the TurboModuleContext integration is enabled by default).
- Capture any event while no TurboModule call is active — e.g.
Sentry.captureMessage('test') from a Pressable's onPress.
- Open the event in Sentry.
Expected result
Event ingests cleanly. turbo_module.name / turbo_module.method tags are either absent (no active call) or carry the active call's values.
Actual result
Every such event is flagged with Event Processing Errors:
Discarded invalid value — tags.84.1 — expected a non-empty value
Discarded invalid value — tags.85.1 — expected a non-empty value
and the two tags show as <invalid> in the event's Tags section. Since most captures happen outside an active TurboModule call, effectively every JS-captured event carries the Processing Error badge, which is noisy and makes real ingestion problems hard to spot. (contexts.turbo_module is correctly cleared to null; only the tags are affected.)
Root cause
src/js/turbomodule/turboModuleTracker.ts — clearScope deliberately writes an empty-string sentinel into both tags because the native setTag bridge only accepts strings:
// Empty-string sentinel for the "no active call" state. We don't pass
// `undefined` because the native `setTag(key, value)` TurboModule spec
// requires a string ...
const NO_ACTIVE_CALL = '';
function clearScope(scope) {
scope.setContext(CONTEXT_KEY, null);
scope.setTag(TAG_NAME, NO_ACTIVE_CALL);
scope.setTag(TAG_METHOD, NO_ACTIVE_CALL);
}
But Sentry ingestion rejects empty tag values, so the sentinel is discarded at ingestion with a visible processing error on the event.
Suggested fix
We patched this locally (patch-package on 8.19.0) by stripping the sentinel tags in the integration's existing processEvent, which keeps the feature intact (context always preserved; tags preserved whenever they hold real values):
// in turboModuleContextIntegration's processEvent(event):
if (event.tags) {
if (event.tags['turbo_module.name'] === '') {
delete event.tags['turbo_module.name'];
}
if (event.tags['turbo_module.method'] === '') {
delete event.tags['turbo_module.method'];
}
}
Verified on device: with this change the Processing Error disappears and contexts.turbo_module / real tag values are unaffected.
Known limitation of the JS-side fix: native fatal-crash events are assembled by the native SDKs and skip JS processEvent, so a crash occurring outside any TurboModule call can still carry the empty tags. A complete fix probably needs the native scopes to support removing a tag (or the native SDKs to drop empty tag values before sending).
Are you willing to submit a PR?
Happy to turn the processEvent change above into a PR if the approach is acceptable.
OS
SDK
@sentry/react-native8.19.0 (bug present since 8.14.0, when theTurboModuleContextintegration was introduced; still present in 8.19.0)React Native version
0.81.5 (Expo SDK 54, New Architecture, Hermes)
Steps to reproduce
Sentry.init({ dsn })with default integrations (theTurboModuleContextintegration is enabled by default).Sentry.captureMessage('test')from aPressable'sonPress.Expected result
Event ingests cleanly.
turbo_module.name/turbo_module.methodtags are either absent (no active call) or carry the active call's values.Actual result
Every such event is flagged with Event Processing Errors:
and the two tags show as
<invalid>in the event's Tags section. Since most captures happen outside an active TurboModule call, effectively every JS-captured event carries the Processing Error badge, which is noisy and makes real ingestion problems hard to spot. (contexts.turbo_moduleis correctly cleared tonull; only the tags are affected.)Root cause
src/js/turbomodule/turboModuleTracker.ts—clearScopedeliberately writes an empty-string sentinel into both tags because the nativesetTagbridge only accepts strings:But Sentry ingestion rejects empty tag values, so the sentinel is discarded at ingestion with a visible processing error on the event.
Suggested fix
We patched this locally (patch-package on 8.19.0) by stripping the sentinel tags in the integration's existing
processEvent, which keeps the feature intact (context always preserved; tags preserved whenever they hold real values):Verified on device: with this change the Processing Error disappears and
contexts.turbo_module/ real tag values are unaffected.Known limitation of the JS-side fix: native fatal-crash events are assembled by the native SDKs and skip JS
processEvent, so a crash occurring outside any TurboModule call can still carry the empty tags. A complete fix probably needs the native scopes to support removing a tag (or the native SDKs to drop empty tag values before sending).Are you willing to submit a PR?
Happy to turn the
processEventchange above into a PR if the approach is acceptable.