Version
v5
Reanimated Version
v3
Gesture Handler Version
v2
Platforms
Android, iOS
What happened?
When Dimensions.addEventListener('change', …) runs in useAnimatedLayout, the callback passes a worklet to state.modify that assigns _state.window = window, where window comes from destructuring the event payload { window }. In the Reanimated UI worklet runtime (Hermes), that identifier is resolved as a missing global: ReferenceError: Property 'window' doesn't exist, stack shows pnpm_useAnimatedLayoutTs7 / useAnimatedLayout and com.swmansion.worklets.AndroidUIScheduler.triggerUI.
This surfaced in our app when opening react-native-vision-camera (preview attach + orientation / configuration change), which triggers Dimensions change while the bottom sheet layout hook is active. We also saw Illegal node ID on NativeAnimatedNodesManager in nearby runs; the definitive JS error in one capture was the window ReferenceError above.
Fix: rename destructuring to e.g. { window: nextWindowLayout }, assign _state.window = nextWindowLayout, and return () => subscription.remove() on the Dimensions listener.
Environment (bare)
- @gorhom/bottom-sheet: ^5.2.8
- react-native: 0.79.7
- expo: 53
- renimated: "3.17.5
diff --git a/src/hooks/useAnimatedLayout.ts b/src/hooks/useAnimatedLayout.ts
index 68c674de6287b89a97be778f7e5273f6b6b1c929..d3be2b5ba243476b616ab3e5e555d45b6e974a83 100644
--- a/src/hooks/useAnimatedLayout.ts
+++ b/src/hooks/useAnimatedLayout.ts
@@ -106,13 +106,14 @@ export function useAnimatedLayout(
[state, verticalInset, modal]
);
useEffect(() => {
- Dimensions.addEventListener('change', ({ window }) => {
+ const subscription = Dimensions.addEventListener('change', ({ window: nextWindowLayout }) => {
state.modify(_state => {
'worklet';
- _state.window = window;
+ _state.window = nextWindowLayout;
return _state;
});
});
+ return () => subscription.remove();
}, [state]);
//#endregion
Reproduction steps
- Open the app with Bottom Sheet at snap index 1 (~90%).
- Tap "Abrir câmera (landscape)" inside the sheet.
- App locks orientation to landscape.
- Observe bottom sheet behavior.
Reproduction sample
https://snack.expo.dev/@luis.agottani95/bottom-sheet---issue-reproduction-template
Relevant log output
<details>
<summary>Logcat excerpt (click to expand)</summary>
# --- NativeAnimated (few seconds earlier, same pid) ---
05-15 18:18:08.190 12348 12348 E unknown:NativeAnimatedNodesManager: Native animation workaround, frame lost as result of race condition
05-15 18:18:08.190 12348 12348 E unknown:NativeAnimatedNodesManager: com.facebook.react.bridge.JSApplicationCausedNativeException: Illegal node ID set as an input for Animated.Add node
05-15 18:18:08.190 12348 12348 E unknown:NativeAnimatedNodesManager: at com.facebook.react.animated.AdditionAnimatedNode.update(AdditionAnimatedNode.kt:44)
05-15 18:18:08.190 12348 12348 E unknown:NativeAnimatedNodesManager: at com.facebook.react.animated.NativeAnimatedNodesManager.updateNodes(NativeAnimatedNodesManager.java:804)
05-15 18:18:08.190 12348 12348 E unknown:NativeAnimatedNodesManager: at com.facebook.react.animated.NativeAnimatedNodesManager.runUpdates(NativeAnimatedNodesManager.java:669)
05-15 18:18:08.190 12348 12348 E unknown:NativeAnimatedNodesManager: at com.facebook.react.animated.NativeAnimatedModule$1.doFrameGuarded(NativeAnimatedModule.java:251)
05-15 18:18:08.191 12348 12348 E unknown:NativeAnimatedNodesManager: Native animation workaround, frame lost as result of race condition
05-15 18:18:08.191 12348 12348 E unknown:NativeAnimatedNodesManager: com.facebook.react.bridge.JSApplicationCausedNativeException: Illegal node ID set as an input for Animated.multiply node
05-15 18:18:08.191 12348 12348 E unknown:NativeAnimatedNodesManager: at com.facebook.react.animated.MultiplicationAnimatedNode.update(MultiplicationAnimatedNode.kt:41)
05-15 18:18:08.191 12348 12348 E unknown:NativeAnimatedNodesManager: at com.facebook.react.animated.NativeAnimatedNodesManager.updateNodes(NativeAnimatedNodesManager.java:804)
# --- Camera attach (same session, ~4s before ReferenceError) ---
05-15 18:18:12.472 12348 12348 I CameraView: CameraView attached to window!
05-15 18:18:12.485 12348 12348 I CameraView: A new configure { ... } call arrived, aborting this one...
# --- ReferenceError: `window` inside worklet path (useAnimatedLayout) ---
05-15 18:18:12.830 12348 12348 W unknown:BridgelessReact: ReactHost{0}.handleHostException(message = "Property 'window' doesn't exist
05-15 18:18:12.830 12348 12348 W unknown:BridgelessReact:
05-15 18:18:12.830 12348 12348 W unknown:BridgelessReact: ReferenceError: Property 'window' doesn't exist
05-15 18:18:12.830 12348 12348 W unknown:BridgelessReact: at pnpm_useAnimatedLayoutTs7 (:1:59)
05-15 18:18:12.830 12348 12348 W unknown:BridgelessReact: at modify (:1:487)
05-15 18:18:12.830 12348 12348 W unknown:BridgelessReact: at pnpm_mutablesTs7 (:1:95)
05-15 18:18:12.830 12348 12348 W unknown:BridgelessReact: at apply (native)
05-15 18:18:12.830 12348 12348 W unknown:BridgelessReact: at anonymous (:1:118)
05-15 18:18:12.830 12348 12348 W unknown:BridgelessReact: at forEach (native)
05-15 18:18:12.830 12348 12348 W unknown:BridgelessReact: at pnpm_threadsTs5 (:1:85)")
05-15 18:18:12.839 12348 12472 W unknown:BridgelessReact: ReactHost{0}.raiseSoftException(getOrCreateDestroyTask()): handleHostException(message = "Property 'window' doesn't exist
05-15 18:18:12.839 12348 12472 W unknown:BridgelessReact:
05-15 18:18:12.839 12348 12472 W unknown:BridgelessReact: ReferenceError: Property 'window' doesn't exist
05-15 18:18:12.839 12348 12472 W unknown:BridgelessReact: at pnpm_useAnimatedLayoutTs7 (:1:59)
05-15 18:18:12.839 12348 12472 W unknown:BridgelessReact: at modify (:1:487)
05-15 18:18:12.839 12348 12472 W unknown:BridgelessReact: at pnpm_mutablesTs7 (:1:95)
05-15 18:18:12.839 12348 12472 W unknown:BridgelessReact: at apply (native)
05-15 18:18:12.839 12348 12472 W unknown:BridgelessReact: at anonymous (:1
Version
v5
Reanimated Version
v3
Gesture Handler Version
v2
Platforms
Android, iOS
What happened?
When Dimensions.addEventListener('change', …) runs in useAnimatedLayout, the callback passes a worklet to state.modify that assigns _state.window = window, where window comes from destructuring the event payload { window }. In the Reanimated UI worklet runtime (Hermes), that identifier is resolved as a missing global: ReferenceError: Property 'window' doesn't exist, stack shows pnpm_useAnimatedLayoutTs7 / useAnimatedLayout and com.swmansion.worklets.AndroidUIScheduler.triggerUI.
This surfaced in our app when opening react-native-vision-camera (preview attach + orientation / configuration change), which triggers Dimensions change while the bottom sheet layout hook is active. We also saw Illegal node ID on NativeAnimatedNodesManager in nearby runs; the definitive JS error in one capture was the window ReferenceError above.
Fix: rename destructuring to e.g. { window: nextWindowLayout }, assign _state.window = nextWindowLayout, and return () => subscription.remove() on the Dimensions listener.
Environment (bare)
Reproduction steps
Reproduction sample
https://snack.expo.dev/@luis.agottani95/bottom-sheet---issue-reproduction-template
Relevant log output