react-native-reanimated
react-native-reanimated copied to clipboard
Calling `runOnJS` on a remote function marked as worklet throws "Attempted to extract from a HostObject that wasn't converted to a Shareable"
Description
The following error appears when trying to call runOnJS
on a function which is also marked as worklet.
ReanimatedError: Exception in HostFunction: [Reanimated] Attempted to extract from a HostObject that wasn't converted to a Shareable., js engine: reanimated
Steps to reproduce
function RemoteFunctionWorkletDemo() {
const someFunction = (x: number) => {
'worklet'; // this is a worklet but we will call it as a remote function
console.log(_WORKLET, x); // _WORKLET should be false
};
const someWorklet = (x: number) => {
'worklet';
console.log(_WORKLET, x); // _WORKLET should be true
runOnJS(someFunction)(x);
};
const handlePress = () => {
runOnUI(someWorklet)(Math.random());
};
return <Button onPress={handlePress} title="RemoteFunctionWorkletDemo" />;
}
Snack or a link to a repository
no
Reanimated version
3.6.0
React Native version
0.72.6
Platforms
Android, iOS
JavaScript runtime
Hermes
Workflow
React Native
Architecture
Paper (Old Architecture)
Build type
Debug mode
Device
iOS simulator
Device model
iPhone 15 Pro
Acknowledgements
Yes
Workaround
Remove 'worklet';
directive.
function RemoteFunctionWorkletDemo() {
const someFunction = (x: number) => {
- 'worklet';
console.log(_WORKLET, x); // _WORKLET should be false
};
const someWorklet = (x: number) => {
'worklet';
console.log(_WORKLET, x); // _WORKLET should be true
runOnJS(someFunction)(x);
};
const handlePress = () => {
runOnUI(someWorklet)(Math.random());
};
return <Button onPress={handlePress} title="RemoteFunctionWorkletDemo" />;
}
Thanks @JDBoots for reporting this in https://github.com/software-mansion/react-native-reanimated/issues/5322#issuecomment-1833547242.
Cant use workaround as it seems to be used like this in gesture handler and some other libs. Also cant really replicate it locally but users are crashing from it.
Here is my android stack trace if this helps:
Exception com.facebook.jni.CppException: Exception in HostFunction: [Reanimated] Attempted to extract from a HostObject that wasn't converted to a Shareable.
Error: Exception in HostFunction: [Reanimated] Attempted to extract from a HostObject that wasn't converted to a Shareable.
at _scheduleOnJS (native)
at anonymous (JavaScript:1:453)
at anonymous (JavaScript:1:212)
at anonymous (JavaScript:1:638)
at handleAndFlushAnimationFrame (JavaScript:1:148)
at com.swmansion.reanimated.nativeProxy.EventHandler.receiveEvent
at com.swmansion.reanimated.nativeProxy.EventHandler.receiveEvent (EventHandler.java:25)
at com.swmansion.gesturehandler.react.RNGestureHandlerStateChangeEvent.dispatch (RNGestureHandlerStateChangeEvent.kt:50)
at com.swmansion.reanimated.NodesManager.handleEvent (NodesManager.java:327)
at com.swmansion.reanimated.NodesManager.onEventDispatch (NodesManager.java:313)
at com.facebook.react.uimanager.events.EventDispatcherImpl.dispatchEvent (EventDispatcherImpl.java:116)
at com.swmansion.gesturehandler.ReactContextExtensionsKt.dispatchEvent (ReactContextExtensions.kt:9)
at com.swmansion.gesturehandler.react.RNGestureHandlerModule.sendEventForDirectEvent (RNGestureHandlerModule.kt:605)
at com.swmansion.gesturehandler.react.RNGestureHandlerModule.sendEventForReanimated (RNGestureHandlerModule.kt:591)
at com.swmansion.gesturehandler.react.RNGestureHandlerModule.onStateChange (RNGestureHandlerModule.kt:543)
at com.swmansion.gesturehandler.react.RNGestureHandlerModule.access$onStateChange (RNGestureHandlerModule.kt:49)
at com.swmansion.gesturehandler.react.RNGestureHandlerModule$eventListener$1.onStateChange (RNGestureHandlerModule.kt:312)
at com.swmansion.gesturehandler.core.GestureHandler.dispatchStateChange (GestureHandler.kt:84)
at com.swmansion.gesturehandler.core.GestureHandlerOrchestrator.onHandlerStateChange (GestureHandlerOrchestrator.kt:133)
at com.swmansion.gesturehandler.core.GestureHandler.moveToState (GestureHandler.kt:558)
at com.swmansion.gesturehandler.core.GestureHandler.cancel (GestureHandler.kt:647)
at com.swmansion.gesturehandler.core.GestureHandlerOrchestrator.cancelAll (GestureHandlerOrchestrator.kt:215)
at com.swmansion.gesturehandler.core.GestureHandlerOrchestrator.onTouchEvent (GestureHandlerOrchestrator.kt:39)
at com.swmansion.gesturehandler.react.RNGestureHandlerRootHelper.dispatchTouchEvent (RNGestureHandlerRootHelper.kt:101)
at com.swmansion.gesturehandler.react.RNGestureHandlerRootView.dispatchTouchEvent (RNGestureHandlerRootView.kt:36)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3286)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2990)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3286)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2990)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3286)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2990)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3286)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2990)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3286)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2990)
at android.view.ViewGroup.dispatchTransformedTouchEvent (ViewGroup.java:3286)
at android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2990)
at com.android.internal.policy.DecorView.superDispatchTouchEvent (DecorView.java:1116)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent (PhoneWindow.java:1971)
at android.app.Activity.dispatchTouchEvent (Activity.java:4388)
at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent (WindowCallbackWrapper.java:70)
at com.android.internal.policy.DecorView.dispatchTouchEvent (DecorView.java:1074)
at android.view.View.dispatchPointerEvent (View.java:15803)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent (ViewRootImpl.java:8153)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess (ViewRootImpl.java:7877)
at android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:7213)
at android.view.ViewRootImpl$InputStage.onDeliverToNext (ViewRootImpl.java:7270)
at android.view.ViewRootImpl$InputStage.forward (ViewRootImpl.java:7236)
at android.view.ViewRootImpl$AsyncInputStage.forward (ViewRootImpl.java:7434)
at android.view.ViewRootImpl$InputStage.apply (ViewRootImpl.java:7244)
at android.view.ViewRootImpl$AsyncInputStage.apply (ViewRootImpl.java:7491)
at android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:7217)
at android.view.ViewRootImpl$InputStage.onDeliverToNext (ViewRootImpl.java:7270)
at android.view.ViewRootImpl$InputStage.forward (ViewRootImpl.java:7236)
at android.view.ViewRootImpl$InputStage.apply (ViewRootImpl.java:7244)
at android.view.ViewRootImpl$InputStage.deliver (ViewRootImpl.java:7217)
at android.view.ViewRootImpl.deliverInputEvent (ViewRootImpl.java:10788)
at android.view.ViewRootImpl.doProcessInputEvents (ViewRootImpl.java:10676)
at android.view.ViewRootImpl.enqueueInputEvent (ViewRootImpl.java:10632)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent (ViewRootImpl.java:10926)
at android.view.InputEventReceiver.dispatchInputEvent (InputEventReceiver.java:285)
at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents
at android.view.InputEventReceiver.consumeBatchedInputEvents (InputEventReceiver.java:262)
at android.view.ViewRootImpl.doConsumeBatchedInput (ViewRootImpl.java:10874)
at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run (ViewRootImpl.java:11020)
at android.view.Choreographer$CallbackRecord.run (Choreographer.java:1301)
at android.view.Choreographer$CallbackRecord.run (Choreographer.java:1309)
at android.view.Choreographer.doCallbacks (Choreographer.java:923)
at android.view.Choreographer.doFrame (Choreographer.java:844)
at android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:1283)
at android.os.Handler.handleCallback (Handler.java:942)
at android.os.Handler.dispatchMessage (Handler.java:99)
at android.os.Looper.loopOnce (Looper.java:226)
at android.os.Looper.loop (Looper.java:313)
at android.app.ActivityThread.main (ActivityThread.java:8762)
at java.lang.reflect.Method.invoke
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:604)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1067)
@tomekzaw Do you want me to post this issue in Gesture handler? Also let me know if there is anything i can help with
Hi @claudesortwell did you figure a workaround for Gesture handler?
I am facing the same
Fatal Exception: com.facebook.jni.CppException: Exception in HostFunction: [Reanimated] Attempted to extract from a HostObject that wasn't converted to a Shareable.
Error: Exception in HostFunction: [Reanimated] Attempted to extract from a HostObject that wasn't converted to a Shareable.
at _scheduleOnJS (native)
at anonymous (JavaScript:1:438)
at anonymous (JavaScript:1:212)
at anonymous (JavaScript:1:629)
at handleAndFlushAnimationFrame (JavaScript:1:148)
at com.swmansion.reanimated.nativeProxy.EventHandler.receiveEvent(EventHandler.java)
at com.swmansion.reanimated.nativeProxy.EventHandler.receiveEvent(EventHandler.java:25)
at com.swmansion.gesturehandler.react.RNGestureHandlerStateChangeEvent.dispatch(RNGestureHandlerStateChangeEvent.kt:42)
at com.swmansion.reanimated.NodesManager.handleEvent(NodesManager.java:327)
at com.swmansion.reanimated.NodesManager.onEventDispatch(NodesManager.java:313)
at com.facebook.react.uimanager.events.EventDispatcherImpl.dispatchEvent(EventDispatcherImpl.java:116)
at com.swmansion.gesturehandler.ReactContextExtensionsKt.dispatchEvent(ReactContextExtensions.kt:9)
at com.swmansion.gesturehandler.react.RNGestureHandlerModule.sendEventForDirectEvent(RNGestureHandlerModule.kt:638)
at com.swmansion.gesturehandler.react.RNGestureHandlerModule.sendEventForReanimated(RNGestureHandlerModule.kt:624)
at com.swmansion.gesturehandler.react.RNGestureHandlerModule.onStateChange(RNGestureHandlerModule.kt:576)
at com.swmansion.gesturehandler.react.RNGestureHandlerModule.access$onStateChange(RNGestureHandlerModule.kt:38)
at com.swmansion.gesturehandler.react.RNGestureHandlerModule$eventListener$1.onStateChange(RNGestureHandlerModule.kt:346)
at com.swmansion.gesturehandler.core.GestureHandler.dispatchStateChange(GestureHandler.kt:84)
at com.swmansion.gesturehandler.core.GestureHandlerOrchestrator.onHandlerStateChange(GestureHandlerOrchestrator.kt:155)
at com.swmansion.gesturehandler.core.GestureHandler.moveToState(GestureHandler.kt:551)
at com.swmansion.gesturehandler.core.GestureHandler.cancel(GestureHandler.kt:640)
at com.swmansion.gesturehandler.core.GestureHandlerOrchestrator.cancelAll(GestureHandlerOrchestrator.kt:244)
at com.swmansion.gesturehandler.core.GestureHandlerOrchestrator.onTouchEvent(GestureHandlerOrchestrator.kt:43)
at com.swmansion.gesturehandler.react.RNGestureHandlerRootHelper.dispatchTouchEvent(RNGestureHandlerRootHelper.kt:97)
at com.swmansion.gesturehandler.react.RNGestureHandlerRootView.dispatchTouchEvent(RNGestureHandlerRootView.kt:35)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3286)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2990)
The gesture is re-throwing the event and the reanimated is listening. I am not able to determine where this is happening
Do you know when this code is executed? @tomekzaw
if (handler.actionType == GestureHandler.ACTION_TYPE_REANIMATED_WORKLET) {
// Reanimated worklet
val event = RNGestureHandlerEvent.obtain(handler, handlerFactory)
sendEventForReanimated(event)
}
I am facing the same
Fatal Exception: com.facebook.jni.CppException: Exception in HostFunction: [Reanimated] Attempted to extract from a HostObject that wasn't converted to a Shareable. Error: Exception in HostFunction: [Reanimated] Attempted to extract from a HostObject that wasn't converted to a Shareable. at _scheduleOnJS (native) at anonymous (JavaScript:1:438) at anonymous (JavaScript:1:212) at anonymous (JavaScript:1:629)
Hi @claudesortwell, @kslbdev, and @tomekzaw, you are right @tomekzaw
in my case was an inline declaration of a function to run in the runOnJS
workletContext {
runOnJS(() => onGestureCancel?.())();
}
For me was happening in the implementation of the react-native-drawer-layout
while using the useAnimatedGestureHandler
For the fix just need to create the function in the JSContext
Check the official fix for this: https://github.com/react-navigation/react-navigation/commit/3cfb3e63949f0aa6f4b14db02161dd88fd10cb12?diff=unified&w=1
@ismaelsousa Thanks a lot for your investigation, fixing this bug at source and letting us know here! You're a hero!
I get this error every time I try to use runOnJS
in useAnimatedReaction
or in a callback function of reanimated. Is there a way to "de-workletise" these or another workaround? I'm on 3.12.0.