[iOS] Fix bad access when decorating runtime - #4187
Conversation
There was a problem hiding this comment.
Pull request overview
This PR restores a synchronous/eager path for decorating the Reanimated UI runtime bindings after createGestureHandler became asynchronously scheduled (PR #4179), addressing iOS “bad access” crashes during runtime decoration.
Changes:
- Replaces
setReanimatedAvailable(...)with a synchronousinstallUIRuntimeBindings(): booleanTurboModule API (JS + native). - Updates iOS/Android native modules to expose/install UI runtime bindings on demand (with internal caching via
*_uiRuntimeDecorated). - Triggers UI runtime binding installation during Reanimated initialization (and makes it a no-op on web).
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/react-native-gesture-handler/src/v3/NativeProxy.web.ts | Switches proxy API to installUIRuntimeBindings() on web. |
| packages/react-native-gesture-handler/src/v3/NativeProxy.ts | Switches proxy API to installUIRuntimeBindings() for native platforms. |
| packages/react-native-gesture-handler/src/specs/NativeRNGestureHandlerModule.ts | Updates TurboModule spec: replaces setReanimatedAvailable with installUIRuntimeBindings(): boolean. |
| packages/react-native-gesture-handler/src/RNGestureHandlerModule.web.ts | Implements installUIRuntimeBindings() as a web no-op returning true. |
| packages/react-native-gesture-handler/src/handlers/gestures/reanimatedWrapper.ts | Installs UI runtime bindings during Reanimated init; introduces worklets initialization step. |
| packages/react-native-gesture-handler/apple/RNGestureHandlerModule.mm | Moves decoration behind exported installUIRuntimeBindings and renames internal decorator helper. |
| packages/react-native-gesture-handler/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt | Exposes installUIRuntimeBindings() and removes lazy decoration tied to handler creation. |
Comments suppressed due to low confidence (1)
packages/react-native-gesture-handler/src/handlers/gestures/reanimatedWrapper.ts:92
Worklets?.scheduleOnUI(() => ...)will still throw ifscheduleOnUIis missing/non-callable (optional chaining here only guardsWorkletsitself). To avoid startup crashes, guard the call (e.g.,Worklets?.scheduleOnUI?.(...)or atypeofcheck), and keep runtime binding installation working even when worklets don’t expose this API.
// Make sure worklets are initialized before attemting to install UI runtime bindings
Worklets?.scheduleOnUI(() => {
'worklet';
});
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Hi @migueldaipre!
That would be great. You can open new issue, then it will be easier to track. Also, what is the first error message? The screens shows second one and maybe on the first there's something that would help us. |
|
As a quick smoke test, can you try a clean rebuild of the app? That method has been added to the native module in |
|
Hey everyone, sorry, it was a false alarm. It was probably just a cache issue, as @j-piasecki pointed out. Thank you for your time. cc @m-bert |

Description
After #4179
createGestureHandleris no longer synchronous - it's batched and scheduled asynchronously. This behavior change caused the runtime decoration to fail with bad access errors. This PR restores the previous synchronous flow of UI runtime decoration. The main difference is doing it eagerly on startup instead of lazily.Test plan
Run the iOS app; it should not crash.