question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

TypeError: Attempting to define property on object that is not extensible

See original GitHub issue

Description

Got red error screen in iOS:

TypeError: Attempting to define property on object that is not extensible.

This error is located at:
    in AnimatedComponent(View) (at createAnimatedComponent.js:459)
    in ForwardRef(AnimatedComponentWrapper) (at StackItem.tsx:178)
    in PanGestureHandler (at StackItem.tsx:172)
    in ForwardRef
    in ForwardRef (at Stack.tsx:101)
    in RCTView (at View.js:34)
    in View (at Stack.tsx:115)
    in Unknown (at Swiper.tsx:271)
    in RCTView (at View.js:34)
    in View (at Swiper.tsx:285)
    in RCTView (at View.js:34)
    in View (at Swiper.tsx:283)
    in SwiperScreen (at SceneView.tsx:122)
    in StaticContainer
    in StaticContainer (at SceneView.tsx:115)
    in EnsureSingleNavigator (at SceneView.tsx:114)
    in SceneView (at useDescriptors.tsx:153)
    in RCTView (at View.js:34)
    in View (at createAnimatedComponent.js:165)
    in AnimatedComponent (at createAnimatedComponent.js:215)
    in ForwardRef(AnimatedComponentWrapper) (at BottomNavigation.tsx:649)
    in RCTView (at View.js:34)
    in View (at createAnimatedComponent.js:165)
    in AnimatedComponent (at createAnimatedComponent.js:215)
    in ForwardRef(AnimatedComponentWrapper) (at BottomNavigation.tsx:634)
    in RCTView (at View.js:34)
    in View (at BottomNavigation.tsx:609)
    in RCTView (at View.js:34)
    in View (at BottomNavigation.tsx:608)
    in BottomNavigation (created by Context.Consumer)
    in ThemedComponent (created by withTheme(BottomNavigation))
    in withTheme(BottomNavigation) (at MaterialBottomTabView.tsx:98)
    in MaterialBottomTabViewInner (at MaterialBottomTabView.tsx:198)
    in MaterialBottomTabView (at createMaterialBottomTabNavigator.tsx:45)
    in MaterialBottomTabNavigator (at main-bottom-tabs/index.tsx:39)
    in MainBottomTabs (at SceneView.tsx:122)
    in StaticContainer
    in StaticContainer (at SceneView.tsx:115)
    in EnsureSingleNavigator (at SceneView.tsx:114)
    in SceneView (at useDescriptors.tsx:153)
    in RCTView (at View.js:34)
    in View (at CardContainer.tsx:245)
    in RCTView (at View.js:34)
    in View (at CardContainer.tsx:244)
    in RCTView (at View.js:34)
    in View (at CardSheet.tsx:33)
    in ForwardRef(CardSheet) (at Card.tsx:573)
    in RCTView (at View.js:34)
    in View (at createAnimatedComponent.js:165)
    in AnimatedComponent (at createAnimatedComponent.js:215)
    in ForwardRef(AnimatedComponentWrapper) (at Card.tsx:555)
    in PanGestureHandler (at GestureHandlerNative.tsx:13)
    in PanGestureHandler (at Card.tsx:549)
    in RCTView (at View.js:34)
    in View (at createAnimatedComponent.js:165)
    in AnimatedComponent (at createAnimatedComponent.js:215)
    in ForwardRef(AnimatedComponentWrapper) (at Card.tsx:544)
    in RCTView (at View.js:34)
    in View (at Card.tsx:538)
    in Card (at CardContainer.tsx:206)
    in CardContainer (at CardStack.tsx:623)
    in RCTView (at View.js:34)
    in View (at Screens.tsx:84)
    in MaybeScreen (at CardStack.tsx:616)
    in RCTView (at View.js:34)
    in View (at Screens.tsx:54)
    in MaybeScreenContainer (at CardStack.tsx:498)
    in CardStack (at StackView.tsx:462)
    in KeyboardManager (at StackView.tsx:458)
    in SafeAreaProviderCompat (at StackView.tsx:455)
    in RCTView (at View.js:34)
    in View (at StackView.tsx:454)
    in StackView (at createStackNavigator.tsx:87)
    in StackNavigator (at main-stack-navigator/index.tsx:61)
    in MainStackNavigator (at SceneView.tsx:122)
    in StaticContainer
    in StaticContainer (at SceneView.tsx:115)
    in EnsureSingleNavigator (at SceneView.tsx:114)
    in SceneView (at useDescriptors.tsx:153)
    in RCTView (at View.js:34)
    in View (at CardContainer.tsx:245)
    in RCTView (at View.js:34)
    in View (at CardContainer.tsx:244)
    in RCTView (at View.js:34)
    in View (at CardSheet.tsx:33)
    in ForwardRef(CardSheet) (at Card.tsx:573)
    in RCTView (at View.js:34)
    in View (at createAnimatedComponent.js:165)
    in AnimatedComponent (at createAnimatedComponent.js:215)
    in ForwardRef(AnimatedComponentWrapper) (at Card.tsx:555)
    in PanGestureHandler (at GestureHandlerNative.tsx:13)
    in PanGestureHandler (at Card.tsx:549)
    in RCTView (at View.js:34)
    in View (at createAnimatedComponent.js:165)
    in AnimatedComponent (at createAnimatedComponent.js:215)
    in ForwardRef(AnimatedComponentWrapper) (at Card.tsx:544)
    in RCTView (at View.js:34)
    in View (at Card.tsx:538)
    in Card (at CardContainer.tsx:206)
    in CardContainer (at CardStack.tsx:623)
    in RCTView (at View.js:34)
    in View (at Screens.tsx:84)
    in MaybeScreen (at CardStack.tsx:616)
    in RCTView (at View.js:34)
    in View (at Screens.tsx:54)
    in MaybeScreenContainer (at CardStack.tsx:498)
    in CardStack (at StackView.tsx:462)
    in KeyboardManager (at StackView.tsx:458)
    in SafeAreaProviderCompat (at StackView.tsx:455)
    in RCTView (at View.js:34)
    in View (at StackView.tsx:454)
    in StackView (at createStackNavigator.tsx:87)
    in StackNavigator (at RootNavigator.tsx:64)
    in RootNavigator (at App.tsx:44)
    in EnsureSingleNavigator (at BaseNavigationContainer.tsx:409)
    in ForwardRef(BaseNavigationContainer) (at NavigationContainer.tsx:91)
    in ThemeProvider (at NavigationContainer.tsx:90)
    in ForwardRef(NavigationContainer) (at App.tsx:36)
    in RNCSafeAreaProvider (at SafeAreaContext.tsx:76)
    in SafeAreaProvider (at App.tsx:35)
    in RCTView (at View.js:34)
    in View (created by MenuProvider)
    in RCTView (at View.js:34)
    in View (created by MenuProvider)
    in MenuProvider (at App.tsx:34)
    in ApolloProvider (at App.tsx:29)
    in PersistGate (at redux-provider.tsx:9)
    in Provider (at redux-provider.tsx:8)
    in ReduxProvider (at App.tsx:28)
    in RCTView (at View.js:34)
    in View (at ActionSheet/index.ios.tsx:17)
    in ActionSheet (at ActionSheetProvider.tsx:31)
    in ActionSheetProvider (at App.tsx:27)
    in App (at renderApplication.js:45)
    in RCTView (at View.js:34)
    in View (at AppContainer.js:106)
    in RCTView (at View.js:34)
    in View (at AppContainer.js:132)
    in AppContainer (at renderApplication.js:39)

Expected behavior

No errors or better description.

Actual behavior & steps to reproduce

On app launch.

Snack or minimal code example

Probably problem is in one of these worklets:

const getAnimationEndX = (
  action: SwipeAction | undefined,
  windowWidth: number,
) => {
  'worklet';
  return action === SwipeAction.Like
    ? windowWidth * 2
    : action === SwipeAction.Dislike
    ? -windowWidth * 2
    : 0;
};

const getAnimationEndY = (
  action: SwipeAction | undefined,
  windowHeight: number,
) => {
  'worklet';
  return action === SwipeAction.SuperLike ? -windowHeight * 2 : 0;
};

// .. later inside component

const applyAction = (action: SwipeAction, triggerCallback = true) => {
  'worklet';

  translateX.value = withTiming(
    getAnimationEndX(action, windowWidth),
    DEFAULT_ANIMATION_CONFIG,
  );
  translateY.value = withTiming(
    getAnimationEndY(action, windowHeight),
    action === SwipeAction.SuperLike
      ? { duration: 700 }
      : DEFAULT_ANIMATION_CONFIG,
  );

  runOnJS(onSwiped)(item, action, triggerCallback);
};

All there worklets are called from both JS and UI threads.

Package versions

  • React Native: 0.63.4
  • React Native Reanimated: 2.2.0 and 2.2.1
  • NodeJS: v14.17.6
  • Xcode: 12.5.1
  • “react-native-gesture-handler”: “1.10.3”,

Affected platforms

  • [?] Android
  • iOS
  • Web

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:9 (3 by maintainers)

github_iconTop GitHub Comments

3reactions
piaskowykcommented, Sep 16, 2021

@Gentlee So actually this is not a bug but it is just how worklet woks. I prepared a showcase to explain it. Look at this:

import React from 'react';
import { View, Button } from 'react-native';
import Animated, { useAnimatedGestureHandler } from 'react-native-reanimated';
import { PanGestureHandler } from 'react-native-gesture-handler';

function Component() {

  const testObject = {
    a: 1
  };

  const gestureHandler = useAnimatedGestureHandler({
    onStart: () => {
      'worklet'
      console.log("is UI:", _WORKLET)
      testObject.a = 2;
    }
  });

  const changeValue = () => {
    testObject.a = 2;
  };

  return (
    <View>
      <PanGestureHandler onGestureEvent={gestureHandler}>
        <Animated.View
          style={{ width: 200, height: 80, backgroundColor: 'black', margin: 30 }}
        />
      </PanGestureHandler>
      <Button title="click" onPress={() => changeValue()} />
    </View>
  );
}

export default Component;

onStart function inside useAnimatedGestureHandler is a worklet. onStart uses testObject - in other words onStart have testObject in own closure. Here starts the harder part. During creating a worklet we froze all variables/objects from worklet’s closuer so after creating worklet testObject is immutable for other threads then UI thread - especially you can’t change a value of an object from JS thread. If you press button from this example you call to function changeValue and you try to change the value of the frozen object ant this operation throws TypeError: Attempted to assign to read-only property. error.

I think that exactly happens in your case. Especially if you pass item to worklet - React Component I guess - you froze the whole component.

Let me know if you have more questions.

2reactions
piaskowykcommented, Sep 16, 2021

@galgord It depends on your specific case. But generally, you need to avoid passing objects directly to the worklet if you want to modify them from other threads. Only SharedValue (useSharedValue) can be modified from any thread. If you want to modify the object from the UI and JS thread instead of a passing object to the worklet you can pass the setter and call it in with runOnJS().

My example with working setter:

import React from 'react';
import { View, Button } from 'react-native';
import Animated, { useAnimatedGestureHandler, runOnJS } from 'react-native-reanimated';
import { PanGestureHandler } from 'react-native-gesture-handler';

function Component() {

  const testObject = {
    a: 1
  };

  const setter = (value) => {
    testObject.a = value;
  }

  const gestureHandler = useAnimatedGestureHandler({
    onStart: () => {
      'worklet'
      console.log("is UI:", _WORKLET)
      runOnJS(setter)(2);
    }
  });

  const changeValue = () => {
    testObject.a = 2;
  };

  return (
    <View>
      <PanGestureHandler onGestureEvent={gestureHandler}>
        <Animated.View
          style={{ width: 200, height: 80, backgroundColor: 'black', margin: 30 }}
        />
      </PanGestureHandler>
      <Button title="click" onPress={() => changeValue()} />
    </View>
  );
}

export default Component;

Is it the answer to your question?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Attempting to define property on object that is not extensible.
Description I'm using useAnimatedGestureHandler to map the gesture events.
Read more >
Object is not extensible error when creating new attribute for ...
data when calling the function), but this didn't seem to be a problem as newData is a new copy of data array... I'm...
Read more >
JavaScript TypeError - Can't define property "X": "Obj" is not ...
This JavaScript exception can't define property “x”: “obj” is not extensible occurs when Object.preventExtensions() used on an object to make it ...
Read more >
cannot add property onclick, object is not extensible - You.com
In strict mode, attempting to add new properties to a non-extensible object throws a TypeError. In sloppy mode, the addition of the "x"...
Read more >
Can't define property object not extensible - Upokary
This error occurs when an object is no longer extensible so that it will never have properties beyond the ones it had at...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found