Skip to content

[Android] formSheet crashes with IllegalArgumentException: invalid pointerIndex -1 (BottomSheetBehavior / ViewDragHelper) on touch #4257

Description

@hoonjoo-park

Description

On Android, screens presented with presentation: "formSheet" occasionally crash with a fatal java.lang.IllegalArgumentException: invalid pointerIndex -1 for MotionEvent. We see this in production (Firebase Crashlytics) across users; it is not caused by app JS.

react-native-screens hosts a formSheet screen inside a CoordinatorLayout with a Material BottomSheetBehavior<Screen> (ScreenStackFragment.createBottomSheetBehaviour()). When the sheet is being dragged, Material's BottomSheetBehavior.onTouchEvent delegates to androidx.customview.widget.ViewDragHelper.processTouchEvent, which on ACTION_MOVE calls MotionEvent.getX(findPointerIndex(mActivePointerId)). If the active pointer id has already desynced (pointer lifted / multi-touch / sheet dismiss or relayout mid-drag / some OEM edge & palm-rejection gestures), findPointerIndex returns -1 and getX(-1) throws. Since RNS delegates sheet dragging to Material, there is no guard and the app crashes.

Stack trace

Fatal Exception: java.lang.IllegalArgumentException: invalid pointerIndex -1 for MotionEvent { action=MOVE, id[0]=0, x[0]=685.5, y[0]=812.8, ... , source=TOUCHSCREEN }
    at android.view.MotionEvent.nativeGetAxisValue(MotionEvent.java)
    at android.view.MotionEvent.getX(MotionEvent.java:3230)
    at androidx.customview.widget.ViewDragHelper.processTouchEvent(ViewDragHelper.java:1195)
    at com.google.android.material.bottomsheet.BottomSheetBehavior.onTouchEvent(BottomSheetBehavior.java:705)
    at androidx.coordinatorlayout.widget.CoordinatorLayout.onTouchEvent(CoordinatorLayout.java:594)
    at android.view.View.dispatchTouchEvent(View.java:17550)
    ...
    at com.swmansion.gesturehandler.react.RNGestureHandlerRootView.dispatchTouchEvent(RNGestureHandlerRootView.kt:40)
    ...
    at android.app.Activity.dispatchTouchEvent(Activity.java:4925)

Steps to reproduce

Not deterministically reproducible — it is a touch-timing race and only shows up in the field. It happens while interacting with (dragging) a formSheet on Android. Likely triggers: a quick fling followed by finger lift, a second pointer, the sheet being dismissed/relaid-out mid-drag, or OEM edge/palm-rejection gestures that produce an unbalanced pointer stream.

Snack / minimal reproduction

No reliable minimal repro (production race). Happy to provide more Crashlytics data or test a candidate fix on our production traffic if that helps.

Expected

Dragging a formSheet should never crash the app on a transient/desynced pointer. RNS could defensively guard the sheet container's touch dispatch against this known Material/ViewDragHelper defect.

Proposed fix / workaround

Guard the sheet host's touch entry point — e.g. wrap the onTouchEvent / dispatchTouchEvent of the sheet's CoordinatorLayout (or the RNS sheet container) in a try/catch (IllegalArgumentException) and drop the offending event. This mirrors how apps already work around the same upstream ViewDragHelper race today. If a PR would be welcome, I'm happy to open one.

react-native-screens version

4.23.0 (also reproduced-by-signature review against 4.24.0 / 4.25.2 — no related change in the changelog)

React Native version

0.83.2 (React 19.2.0)

Platform

Android

Additional environment

  • Expo SDK 55, expo-router 55
  • New Architecture (Fabric) enabled, Hermes
  • react-native-gesture-handler 2.30.0, react-native-reanimated 4.2.1
  • @sentry/react-native 7.11.0 (session replay enabled — appears only as a dispatch wrapper in the trace, not the cause)

Notes

  • Searched existing issues/PRs for pointerIndex / ViewDragHelper — no existing report found.
  • Related upstream context (same ViewDragHelper family, different exception): material-components-android No method setReorderingAllowed found #43, docs: fix search bar only for iOS #1295 (those were NullPointerExceptions fixed long ago; this IllegalArgumentException: invalid pointerIndex -1 path is a separate, still-unguarded race).

Metadata

Metadata

Assignees

No one assigned

    Labels

    missing-infoThe user didn't precise the problem enoughmissing-reproThis issue need minimum repro scenarioplatform:androidIssue related to Android part of the library

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions