Skip to content

Session Replay: fatal NSInvalidArgumentException in RNSentryReplayBreadcrumbConverter (objectForKey: on non-dictionary touch-path element) #6342

Description

@chuckcg

What React Native libraries do you use?

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

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.0.0 (unguarded code also present on main / 8.15.x)

How does your development environment look like?

  • @sentry/react-native: 8.0.0
  • react-native: 0.81.5
  • Expo SDK 54 (expo 54.0.33), Hermes enabled
  • New Architecture (Fabric + TurboModules): enabled
  • Affected platform: iOS (native crash); seen on iOS 17–26.x, physical devices (iPhone15,3)
  • Package manager: pnpm (monorepo)

Sentry.init()

Sentry.init({
  dsn: 'https://<redacted>@<org>.ingest.sentry.io/<project>',
  integrations: [Sentry.reactNavigationIntegration(), Sentry.mobileReplayIntegration()],
  replaysSessionSampleRate: 0.03,
  replaysOnErrorSampleRate: 1.0,
});

Steps to Reproduce

  1. Initialize the SDK with Session Replay enabled (mobileReplayIntegration + a non-zero replaysSessionSampleRate) on iOS.
  2. Let the app record touch interactions while a replay segment is being captured.
  3. When a touch breadcrumb's path array contains a non-dictionary element, the native replay breadcrumb converter crashes.

(Intermittent — depends on the touch-breadcrumb payload shape. Observed in production across multiple users; not a controlled repro.)

Expected Result

The replay breadcrumb converter should skip/ignore a malformed touch-path element instead of crashing the app.

Actual Result

Fatal NSInvalidArgumentException on the replay's background dispatch queue → uncaught → SIGABRT.

NSInvalidArgumentException: -[__NSCFString objectForKey:]: unrecognized selector sent to instance
  +[RNSentryReplayBreadcrumbConverter getTouchPathMessageFrom:]
  -[RNSentryReplayBreadcrumbConverter convertTouch:]
  -[RNSentryReplayBreadcrumbConverter convertFrom:]
  SentrySessionReplay.convertBreadcrumbs (SentrySessionReplay.swift)
  SentrySessionReplay.captureSegment / processNewlyAvailableSegment
  SentryOnDemandReplay.createVideoInBackgroundWith (SentryOnDemandReplay.swift)
  _SentryDispatchQueueWrapperInternal dispatchAsyncWithBlock:

Root cause — in packages/core/ios/RNSentryReplayBreadcrumbConverter.m, getTouchPathMessageFrom: does:

NSDictionary *item = [path objectAtIndex:i];
if (item == nil) { return nil; }
id name = [item objectForKey:@"name"];   // crashes if `item` is an NSString

There is a nil check but no isKindOfClass:[NSDictionary class] guard; convertTouch: likewise subscripts breadcrumb.data guarded only against nil. A non-dictionary element throws unrecognized selector. Verified present in 8.0.0 and on main (latest), so an SDK upgrade does not fix it. convertNavigation: already does the isKindOfClass: check — applying the same guard here resolves it.

Impact: fatal crash, observed 45 times across 3 users in production.

Workaround: disabling Session Replay (removing mobileReplayIntegration() and the replay sample rates) avoids it, since the converter only runs while replay is active.

Metadata

Metadata

Assignees

No fields configured for issues without a type.

Projects

Status
No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions