Repository navigation
[Android] com.facebook.react.views.scroll.ReactScrollView.onTouchEvent java.lang.IllegalArgumentException #3921
Copy link
Copy link
Closed
Labels
Missing infoMissing reproPlatform: AndroidThis issue is specific to AndroidThis issue is specific to Android
Description
Description
Hello, I have a clicker game, and I see a huge number of crashes with an error.
There was pull request #3642, but these changes were not accepted.
Please advise if I can expect this bug to be reviewed.
User-perceived crash rate 4.26%
Almost all crashes are related to this error.
Full log:
Exception java.lang.IllegalArgumentException: pointerIndex out of range
at android.view.MotionEvent.nativeGetAxisValue
at android.view.MotionEvent.getY (MotionEvent.java:2447)
at android.widget.ScrollView.onTouchEvent (ScrollView.java:895)
at com.facebook.react.views.scroll.ReactScrollView.onTouchEvent (ReactScrollView.java:548)
at com.swmansion.gesturehandler.core.NativeViewGestureHandler$NativeViewGestureHandlerHook$DefaultImpls.sendTouchEvent (NativeViewGestureHandler.kt:252)
at com.swmansion.gesturehandler.core.NativeViewGestureHandler$ScrollViewHook.sendTouchEvent (NativeViewGestureHandler.kt:337)
at com.swmansion.gesturehandler.core.NativeViewGestureHandler.onHandle (NativeViewGestureHandler.kt:149)
at com.swmansion.gesturehandler.core.GestureHandler.handle (GestureHandler.kt:392)
at com.swmansion.gesturehandler.core.GestureHandlerOrchestrator.deliverEventToGestureHandler (GestureHandlerOrchestrator.kt:314)
at com.swmansion.gesturehandler.core.GestureHandlerOrchestrator.deliverEventToGestureHandlers (GestureHandlerOrchestrator.kt:266)
at com.swmansion.gesturehandler.core.GestureHandlerOrchestrator.onTouchEvent (GestureHandlerOrchestrator.kt:57)
at com.swmansion.gesturehandler.react.RNGestureHandlerRootHelper.dispatchTouchEvent (RNGestureHandlerRootHelper.kt:119)
at com.swmansion.gesturehandler.react.RNGestureHandlerRootView.dispatchTouchEvent (RNGestureHandlerRootView.kt:37)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3131)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2812)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3131)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2812)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3131)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2812)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3131)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2812)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3131)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2812)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3131)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2812)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3131)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2812)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3131)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2812)
at com.android.internal.policy.DecorView.superDispatchTouchEvent (DecorView.java:572)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent (PhoneWindow.java:1895)
at android.app.Activity.dispatchTouchEvent (Activity.java:4274)
at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent (WindowCallbackWrapper.java:69)
at io.sentry.android.core.internal.gestures.WindowCallbackAdapter.dispatchTouchEvent (WindowCallbackAdapter.java:39)
at io.sentry.android.core.internal.gestures.SentryWindowCallback.dispatchTouchEvent (SentryWindowCallback.java:66)
at io.sentry.android.replay.util.FixedWindowCallback.dispatchTouchEvent (FixedWindowCallback.java:68)
at io.sentry.android.replay.gestures.GestureRecorder$SentryReplayGestureRecorder.dispatchTouchEvent (GestureRecorder.kt:84)
at io.sentry.android.core.internal.gestures.WindowCallbackAdapter.dispatchTouchEvent (WindowCallbackAdapter.java:39)
at io.sentry.android.core.internal.gestures.SentryWindowCallback.dispatchTouchEvent (SentryWindowCallback.java:66)
at com.android.internal.policy.DecorView.dispatchTouchEvent (DecorView.java:530)
at android.view.View.dispatchPointerEvent (View.java:15117)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent (ViewRootImpl.java:6663)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess (ViewRootImpl.java:6458)
at android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:5901)
at android.view.ViewRootImpl$InputStage.onDeliverToNext (ViewRootImpl.java:5958)
at android.view.ViewRootImpl$InputStage.forward (ViewRootImpl.java:5924)
at android.view.ViewRootImpl$AsyncInputStage.forward (ViewRootImpl.java:6089)
at android.view.ViewRootImpl$InputStage.apply (ViewRootImpl.java:5932)
at android.view.ViewRootImpl$AsyncInputStage.apply (ViewRootImpl.java:6146)
at android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:5905)
at android.view.ViewRootImpl$InputStage.onDeliverToNext (ViewRootImpl.java:5958)
at android.view.ViewRootImpl$InputStage.forward (ViewRootImpl.java:5924)
at android.view.ViewRootImpl$InputStage.apply (ViewRootImpl.java:5932)
at android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:5905)
at android.view.ViewRootImpl.deliverInputEvent (ViewRootImpl.java:8906)
at android.view.ViewRootImpl.doProcessInputEvents (ViewRootImpl.java:8857)
at android.view.ViewRootImpl.enqueueInputEvent (ViewRootImpl.java:8825)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent (ViewRootImpl.java:9042)
at android.view.InputEventReceiver.dispatchInputEvent (InputEventReceiver.java:281)
at android.os.MessageQueue.nativePollOnce
at android.os.MessageQueue.next (MessageQueue.java:340)
at android.os.Looper.loopOnce (Looper.java:168)
at android.os.Looper.loop (Looper.java:299)
at android.app.ActivityThread.main (ActivityThread.java:8319)
at java.lang.reflect.Method.invoke
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:556)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1038)
Steps to reproduce
I can't reproduce this on my devices. The usage is approximately as follows:
import {Canvas} from '@shopify/react-native-skia';
import {GestureHandlerRootView, ScrollView, GestureDetector} from 'react-native-gesture-handler';
<ScrollView>
<GestureHandlerRootView>
<GestureDetector gesture={...}>
<Canvas
pointerEvents="none"
....
/>
</GestureDetector>
</GestureHandlerRootView>
</ScrollView>
A link to a Gist, an Expo Snack or a link to a repository based on this template that reproduces the bug.
Gesture Handler version
2.30.0
React Native version
0.81.5
Platforms
Android
JavaScript runtime
Hermes
Workflow
None
Architecture
New Architecture (Fabric)
Build type
None
Device
Real device
Device model
No response
Acknowledgements
Yes
Reacted by Luca Cappelloni, lxr-mwhite and Basil Tarek
Reacted by chengjieLee
Metadata
Metadata
Assignees
Labels
Missing infoMissing reproPlatform: AndroidThis issue is specific to AndroidThis issue is specific to Android
Activity
github-actions commentedon Jan 15, 2026
Hey! 👋
It looks like you've omitted a few important sections from the issue template.
Please complete A link to a Gist, an Expo Snack or a link to a repository based on this template that reproduces the bug. section.
github-actions commentedon Jan 15, 2026
Hey! 👋
The issue doesn't seem to contain a minimal reproduction.
Could you provide a snack or a link to a GitHub repository under your username that reproduces the problem?
lxr-mwhite commentedon Jan 26, 2026
Seeing the exact same issue on the following versions:
And on the legacy architecture.
But most of the crashes I'm seeing occur on Android 16.
I will try to reproduce locally so I can share more info.
These are some related error messages I can see in Crashlytics.
j-piasecki commentedon Jan 27, 2026
I wasn't able to reproduce the issue either, but I might have an idea of what's happening. Would it be possible for you to test this PR: #3933?
exzos28 commentedon Jan 27, 2026
@j-piasecki I don't think I'll be able to conduct a new experiment in production.
At the moment, I've patched in the changes from 3642, and it looks like that has solved all the crashes with the
onTouchEventmethod.lxr-mwhite commentedon Mar 31, 2026
@exzos28 Are you still having success with the patch from #3642?
@j-piasecki Thank you for your fix in #3933.
I haven't been able to try either patch yet, but have still seen both issues on our latest app version so I'm wondering if they are related. They occur about 5-10 times per day and more often on Google Pixels.
On Android 10 I see the exception:
Fatal Exception: java.lang.IllegalArgumentException: pointerIndex out of rangewhile on newer versions (mostly Android 16) I see the exception:Fatal Exception: java.lang.IllegalArgumentException: invalid pointerIndex -1 for MotionEvent { action=POINTER_UP(1), id[0]=0, x[0]=757.5, y[0]=114.25, id[1]=3, x[1]=992.25, y[1]=70, flags=SUPPORTS_ORIENTATION, pointerCount=2, eventTime=314555878149000ns, downTime=314555290686000ns, deviceId=4, source=TOUCHSCREEN, displayId=0, eventId=0xd408b67e}.I can possibly try one of these patches in an upcoming release, I'm just unsure if both PRs end up fixing the same thing or if there are two different issues.
j-piasecki commentedon Apr 1, 2026
@lxr-mwhite Those exceptions look like they share the same root cause, so both patches are targeting them. #3642 is simply catching the thrown exception and effectively ignoring it, while #3933 is attempting to address the root cause.
The first one will definitely clear up the issues you're seeing, but I'd appreciate it if you could try the latter (which may not help with the problem).
lxr-mwhite commentedon Apr 1, 2026
@j-piasecki Thank you for the clarification.
I will include a patch with the changes from #3933 in our next release towards the end of the month and report back shortly after.
lxr-mwhite commentedon Apr 24, 2026
@j-piasecki Just providing an update that the latest release of our app including a patch with the changes from your PR #3933 is still experiencing some crashes with the same error that I reported earlier.
So far they have all occurred on Pixel devices running Android 16. (Pixel 8, Pixel 9, Pixel Tablet).
I'm not sure if this is still considered the same error as the one originally reported in this issue. Please let me know if you would prefer a separate issue for this.
j-piasecki commentedon Apr 27, 2026
@lxr-mwhite Do you have enough data to say whether the crash rate was influenced in any way by introducing this patch?
Also, earlier, you mentioned seeing
Fatal Exception: java.lang.IllegalArgumentException: pointerIndex out of rangeon older Android versions. Do you still see it, or did that stop occurring after the patch?lxr-mwhite commentedon Apr 27, 2026
@j-piasecki Good questions and sorry for not providing that information earlier. I was hoping to give it a bit more time to see.
It has now been 5 days since our release, and I would say the crash rate was unfortunately not influenced. I have now also seen the
Fatal Exception: java.lang.IllegalArgumentException: pointerIndex out of rangeon older Android versions with the patch.Some good news is that our app releases will be more frequent now so we should be able to get feedback more quickly. We will be adding some additional logs temporarily to see if we can determine a pattern to help reproduce it locally.
lxr-mwhite commentedon May 10, 2026
@j-piasecki I've been continuing to investigate this crash and try to get reliable reproduction steps but unfortunately have not been able to come up with anything concrete. Though I've also been trying to better understand the
GestureHandlercode and wanted to share a potential solution.Since the crash originates from
ScrollViewHook.sendTouchEvent, which inherits the default implementation and forwards all events to the nativeScrollViewviaview?.onTouchEvent(event), I wonder if we could validate the action and drop the malformed event?I was thinking that
ACTION_POINTER_UPwith apointerCountgreater than 1 means one finger is lifting but one or more are still down so the gesture isn't over yet.onHandle()handlesACTION_UPin its own branch independently ofSTATE_ACTIVE, so the gesture should still transition toENDcleanly when the last finger lifts. Dropping only the malformedPOINTER_UPevent should hopefully not interrupt or freeze the scroll interaction.As a potential solution, can
ScrollViewHookoverridesendTouchEventto validate the action index:I was thinking it might be acceptable to introduce this defensive pattern, similar to what @m-bert introduced for
ACTION_MOVEevents in #4010 (if I understood the changes correctly).While I was not able to reproduce the crash locally through a normal interaction, I was able to confirm the code path by constructing a
MotionEventwith a deliberately invalidactionIndex. This produced a stack trace with the sameIllegalArgumentException: invalid pointerIndex for MotionEvent.j-piasecki commentedon May 12, 2026
That would very likely work as you expect, but it addresses the symptom like #3642 instead of the root cause, which is still not found. It's possible that it's still the best approach, given that the ScrollView is the only report of that issue we've been getting, AFAIK.
lxr-mwhite commentedon May 12, 2026
@j-piasecki I appreciate all the help on this!
I've looked at some additional logs and tried to pay close attention to the actual coordinates of the pointers causing the crash, and have found some of them pretty fascinating. For every
invalid pointerIndex -1 for MotionEventcrash, I noticed it was thePOINTER_UPaction with apointerCount > 1. I've noticed in some instances that theycoordinate is negative, which I don't understand. I've seen it crash in areas of my app where we don't even have anything on the screen that would suggest a multi touch gesture is available. And finally, I've noticed some users experience crashes within the first few seconds while others do after a few minutes.Since it doesn't seem like anyone else is facing this issue, I have to start thinking it might be related to something specific in mine. So after collecting a few logs and crash reports I've looked at some of the code in the areas where the crashes occur and found a few things that I will change for our next release.
ScrollViewimported fromreact-native-gesture-handler. Found a couple screens where that is the case, so I will replace those imports with the ones fromreact-native.NativeViewGestureHandler. One instance wraps aFlatListand a second instance wraps aSectionList. I will useFlatListfromreact-native-gesture-handlerinstead, and for the second component I'll migrate toGestureDetector.[GESTURE HANDLER] Gesture handler is already enabled for a parent view. I found that another one of our dependencies is wrapping its exported component withGestureHandlerRootView. We already wrap ourNavigationContainerwithGestureHandlerRootView, so I will patch the other package to remove itsGestureHandlerRootView.Can't cancel already finished gesture. Is a child View trying to start a gesture from an UP/CANCEL event?. This is logged when our FlatList Item'sGesture.Tap().onEnd()is fired. I don't have a plan for this one yet.Thought I would note these down in case anyone else comes across a similar issue in the future.
j-piasecki commentedon May 12, 2026
Assuming the bug is in RNGH, this will likely get rid of the issue, since the ScrollView's touch events will not go through the Gesture Handler touch system.
Have you tried to check if the snippet you posted above (customized ScrollViewHook) solves the issue in your case? I feel like this is a rare case where a literal
if (goingToCrash) { dont() }may be applicable 😄.lxr-mwhite commentedon May 12, 2026
I will try the patch in my next release as well. I was hesitant at first because it would be harder to tell if the JS changes fixed the issues on their own or not. But one of the most used screens in my app is using an RNGH
ScrollView, and that one I don't think I can replace. So the patch may help with the crashes occurring on that screen.I can report back after trying the
ScrollViewHookpatch.lxr-mwhite commentedon May 13, 2026
@j-piasecki I was finally able to reproduce this locally. Mostly by chance at first, but after further investigation I can now reproduce it fairly reliably.
Unfortunately the
ScrollViewHookchanges didn’t help. I also still have your changes from #3933 applied, but tested both with and without them.I’m reproducing this on an Android 16 emulator. The scenario is:
FlatListon my Main screenFlatListwhile the parent screen is navigating awayI also added a small artificial delay during debugging to make the transition timing easier to hit consistently.
It still doesn’t happen 100% of the time, which may explain why it has been difficult to reproduce locally and why only a relatively small number of users have experienced it in production.
At this point I’m less convinced the root issue is purely in RNGH itself, and more that
ScrollViewis receiving an event sequence that leaves its internal active pointer state inconsistent during the navigation transition.As a temporary mitigation, I may patch
ScrollViewHooklike this:Let me know if there’s any additional logging or instrumentation I can add that would help narrow this down further.
j-piasecki commentedon May 14, 2026
Thank you for the repro steps, I managed to build a small reproducer based on them!
Here it is
You have to tap on any item, start a multi-touch gesture before the navigation starts, and finish it during the navigation animation. I'll look into this more soon.
lxr-mwhite commentedon May 14, 2026
Thank you for all the help @j-piasecki !
j-piasecki commentedon May 14, 2026
@lxr-mwhite Can I ask you to check if #4177 works in your case? It solved the issue in the small reproducer.
lxr-mwhite commentedon May 14, 2026
So far so good! I can confirm the same steps I was reproducing the crash with yesterday no longer produce the crash with the changes from #4177. I even added a breakpoint to verify it goes though the
parent.indexOfChild(current) < 0 -> return falsecode path and confirmed it does.[Android] Fix `ScrollView` invalid pointer id during navigation (soft…