Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: Cannot determine default value of object in 0.4.2-rc1 #205

Closed
janicduplessis opened this issue Apr 2, 2020 · 10 comments
Closed
Labels
need more info Awating additional info before proceeding

Comments

@janicduplessis
Copy link

I'm getting this error after updating to 0.4.2-rc1.

TypeError: Cannot determine default value of object
  at Number(app:///native)
  at sanitizeValue(/Users/janic/Developer/th3rdwave/node_modules/react-native-reanimated/src/core/InternalAnimatedValue.js:8:7)
  at constructor(/Users/janic/Developer/th3rdwave/node_modules/react-native-reanimated/src/core/InternalAnimatedValue.js:35:35)
  at valueForConstant(/Users/janic/Developer/th3rdwave/node_modules/react-native-reanimated/src/core/InternalAnimatedValue.js:30:42)
  at nodify(/Users/janic/Developer/th3rdwave/node_modules/react-native-reanimated/src/core/AnimatedBlock.js:45:29)
  at adapt(/Users/janic/Developer/th3rdwave/node_modules/react-native-reanimated/src/core/AnimatedBlock.js:51:7)
  at createAnimatedCond(/Users/janic/Developer/th3rdwave/node_modules/react-native-reanimated/src/core/AnimatedCond.js:54:5)
  at proc$argument_0(/Users/janic/Developer/th3rdwave/node_modules/react-native-reanimated/src/derived/onChange.js:6:5)
  at apply(app:///native)
  at createAnimatedFunction(/Users/janic/Developer/th3rdwave/node_modules/react-native-reanimated/src/core/AnimatedFunction.js:41:18)
  at <global>(/Users/janic/Developer/th3rdwave/node_modules/react-native-reanimated/src/derived/onChange.js:4:22)
  at loadModuleImplementation(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:321:5)
  at guardedLoadModule(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:210:12)
  at metroRequire(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:128:7)
  at <global>(/Users/janic/Developer/th3rdwave/node_modules/react-native-reanimated/src/derived/index.js:9:1)
  at loadModuleImplementation(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:321:5)
  at guardedLoadModule(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:210:12)
  at metroRequire(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:128:7)
  at <global>(/Users/janic/Developer/th3rdwave/node_modules/react-native-reanimated/src/Animated.js:8:1)
  at loadModuleImplementation(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:321:5)
  at guardedLoadModule(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:210:12)
  at metroRequire(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:128:7)
  at <global>(/Users/janic/Developer/th3rdwave/packages/ui/src/components/Animated/Animated.tsx:3:1)
  at loadModuleImplementation(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:321:5)
  at guardedLoadModule(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:210:12)
  at metroRequire(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:128:7)
  at <global>(/Users/janic/Developer/th3rdwave/packages/ui/src/components/Animated/index.ts:1:1)
  at loadModuleImplementation(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:321:5)
  at guardedLoadModule(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:210:12)
  at metroRequire(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:128:7)
  at <global>(/Users/janic/Developer/th3rdwave/packages/ui/src/components/index.ts:1:1)
  at loadModuleImplementation(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:321:5)
  at guardedLoadModule(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:210:12)
  at metroRequire(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:128:7)
  at <global>(/Users/janic/Developer/th3rdwave/packages/ui/src/index.ts:2:1)
  at loadModuleImplementation(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:321:5)
  at guardedLoadModule(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:210:12)
  at metroRequire(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:128:7)
  at <global>(src/components/App.tsx:16:1)
  at loadModuleImplementation(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:321:5)
  at guardedLoadModule(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:210:12)
  at metroRequire(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:128:7)
  at <global>(index.js:41:13)
  at loadModuleImplementation(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:321:5)
  at guardedLoadModule(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:201:21)
  at metroRequire(/Users/janic/Developer/th3rdwave/node_modules/metro/src/lib/polyfills/require.js:128:7)
  at global(index.android.bundle:222:16)

It happens on app launch. Seem to be triggered by requiring react-native-reanimated.

I cannot reproduce the issue in the simulator (release) and it doesn't seem to happen in all versions of android. I noticed it in the play store pre-launch report. Here's the breakdown of android versions and if the crash happened.

image

Using RN master @ fb9a7be

@mhorowitz
Copy link
Contributor

Thanks for the bug report!

As you can see from the stack trace, this comes from this JS code: https://github.com/software-mansion/react-native-reanimated/blob/master/src/core/InternalAnimatedValue.js#L8

The error message is emitted when the argument passed to Number() is not convertible to a primitive. I can think of a couple ways to cause this to happen offhand, by passing an object which has no toString or valueOf property which can be called:

>> Number(Object.create(null))
TypeError: Cannot determine default value of object
    at Number (native)
    at global (JavaScript:1:7)
>> Number(new Proxy({}, {get() {}}))
TypeError: Cannot determine default value of object
    at Number (native)
    at global (JavaScript:1:7)

JSC also throws an exception with these inputs, but it's different: "TypeError: No default value". Google does find some instances of this error in RN apps, but not related to reanimated as far as I can tell.

I do see that there is code in reanimated which is conditional on the existence of Proxy: https://github.com/software-mansion/react-native-reanimated/blob/2a48891a6c626bc336ba64ca54e785fbdac501f4/src/core/AnimatedEvent.js#L70
I don't know much about reanimated, but it certainly plausible that if a function with the right (wrong?) properties were wrapped using that code and somehow got passed to InternalAnimatedValue, it would result in a crash like this.

If you can reproduce this in the play store, there's a couple things to try:

  1. try hermes-engine@0.4.1 and see if it still happens.
  2. Modify the code to wrap a try/catch around the statement which is throwing the exception, and add some logging to see what value is.

More generally, I would approach this as a bug in JS code, and determine what is causing the invalid input, or come up with a repro case which demonstrates that JS is not behaving according to spec for some particular code or input.

I don't have a theory as to why this behaves differently on different android versions.

@mhorowitz mhorowitz added the need more info Awating additional info before proceeding label Apr 2, 2020
@janicduplessis
Copy link
Author

@mhorowitz I'm really confused about this one. I can confirm that 0.4.1 works fine. The best log I'm able to do around value is typeof which is "object". Any other log triggers the error again since it tries to convert it to a string. I also tried for ... in to log keys but now I'm getting a very weird crash.

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'Sony/G8441/G8441:8.0.0/47.1.A.12.205/2573353275:user/release-keys'
Revision: '0'
ABI: 'arm64'
pid: 17775, tid: 17890, name: mqt_js  >>> com.th3rdwavemerchant <<<
signal 7 (SIGBUS), code 1 (BUS_ADRALN), fault addr 0x40ffff007b2c4361
    x0   0000007b2cbdcab0  x1   0000007b2e29c000  x2   0000000000000002  x3   0000007b2d640128
    x4   0000007b2d63ff70  x5   0000007b2d63ff38  x6   0000007b2d63fea0  x7   0000007b2d63fea0
    x8   40ffff007b2c4361  x9   0000000000000001  x10  0000000000000004  x11  0000000000000004
    x12  0000007b2d63fea0  x13  0000000000000002  x14  0000007b2c400000  x15  0000007b2d640168
    x16  0000007b2dfab620  x17  0000007b4c71c970  x18  000000007ff00000  x19  0000007b2e29c000
    x20  0000000000000002  x21  0000007b2d642588  x22  0000007b2d640170  x23  0000007b2d63ff20
    x24  0000007b2d640198  x25  0000007b2d640188  x26  fff8800000000000  x27  0000007b2d63fea0
    x28  0000000000000004  x29  0000007b2d63fde0  x30  0000007b2de155b4
    sp   0000007b2d63fc80  pc   40ffff007b2c4361  pstate 0000000040000000
backtrace:
    #00 pc 40ffff007b2c4361  <unknown>
    #01 pc 00000000000495b0  /data/data/com.th3rdwavemerchant/lib-0/libhermes.so
    #02 pc 00000000000505b0  /data/data/com.th3rdwavemerchant/lib-0/libhermes.so
    #03 pc 00000000000422dc  /data/data/com.th3rdwavemerchant/lib-0/libhermes.so
    #04 pc 0000000000032f14  /data/data/com.th3rdwavemerchant/lib-0/libhermes.so
    #05 pc 0000000000031c98  /data/data/com.th3rdwavemerchant/lib-0/libhermes.so
    #06 pc 00000000000a1ff4  /data/data/com.th3rdwavemerchant/lib-0/libhermes.so
    #07 pc 0000000000032b14  /data/data/com.th3rdwavemerchant/lib-0/libhermes.so
    #08 pc 0000000000041e44  /data/data/com.th3rdwavemerchant/lib-0/libhermes.so
    #09 pc 0000000000066d08  /data/data/com.th3rdwavemerchant/lib-0/libhermes.so
    #10 pc 0000000000022420  /data/data/com.th3rdwavemerchant/lib-0/libhermes.so
    #11 pc 00000000000226a4  /data/data/com.th3rdwavemerchant/lib-0/libhermes.so
    #12 pc 00000000000245c8  /data/data/com.th3rdwavemerchant/lib-0/libhermes-executor-release.so
    #13 pc 00000000000a1478  /data/data/com.th3rdwavemerchant/lib-0/libreactnativejni.so
    #14 pc 00000000000a2e74  /data/data/com.th3rdwavemerchant/lib-0/libreactnativejni.so
    #15 pc 0000000000069408  /data/data/com.th3rdwavemerchant/lib-0/libreactnativejni.so
    #16 pc 000000000005a25c  /data/data/com.th3rdwavemerchant/lib-0/libreactnativejni.so
    #17 pc 000000000005a1d8  /data/data/com.th3rdwavemerchant/lib-0/libreactnativejni.so
    #18 pc 00000000000bb74c  /data/app/com.th3rdwavemerchant-YWsKaUYbDczCMWvoNzoM0A==/oat/arm64/base.odex (offset 0x90000)

Sadly it isn't symbolicated so not sure what to do about it.

I've also gotten this on Android 5 only...

TypeError: Object is not a function
  at constructor(/Users/janic/Developer/th3rdwave/node_modules/react-native-reanimated/src/core/AnimatedParam.js:12:10)
  at createAnimatedParam(/Users/janic/Developer/th3rdwave/node_modules/react-native-reanimated/src/core/AnimatedParam.js:84:10)
  at createAnimatedFunction(/Users/janic/Developer/th3rdwave/node_modules/react-native-reanimated/src/core/AnimatedFunction.js:38:17)
  at <global>(/Users/janic/Developer/th3rdwave/node_modules/react-native-reanimated/src/derived/onChange.js:4:22)

I find the different behavior on different devices / android versions very odd. Certain work perfectly fine. This is really hard to test for me since I can't repro on a local device.

Also Number(new Proxy({}, {get(target, name) { return target[name]; }})) should work if the proxy returns something in the get. Tested this in safari.

I also played with the code in reanimated a bit. The interesting parts I found is

const proxyHandler = {
      get: function(target, name) {
        if (name === '__isProxy') { // <- Returns true for __isProxy
          return true;
        }
        if (!target[name] && name !== '__val') {
          target[name] = new Proxy({}, proxyHandler);
        }
        return target[name];
      },
      [...]
    };

Then https://github.com/software-mansion/react-native-reanimated/blob/2a48891a6c626bc336ba64ca54e785fbdac501f4/src/core/AnimatedBlock.js#L36 is in the code path that leads to where the crash happens. It should prevent proxies from reaching the Number(...) call in sanitizeValue but looks like it doesn't. I'm also able to trigger a lot of errors by logging this proxy object but not Cannot determine default value of object.

var proxyHandler = {
      get: function (target, name) {
        if (name === '__isProxy') {
          return true;
        }
        if (!target[name] && name !== '__val') {
          target[name] = new Proxy({}, proxyHandler);
        }
        return target[name];
      },
      set: function (target, prop, value) {
        if (prop === '__val') {
          target[prop] = value;
          return true;
        }
        return false;
      },
    };
    Number(new Proxy({}, proxyHandler)); // <- TypeError: Could not get callable method from object

Will report back if I find anything else when I get more time to investigate.

@mhorowitz
Copy link
Contributor

@janicduplessis thanks for digging in. I agree, this is all very strange. The native crash should definitely not happen. My general suggestion would be to rebuild hermes with symbols, but unfortunately, I'm not sure how to tell you to do that with cmake.

I don't envy you trying to debug this without having a local repro. We get those from time to time and they are very hard to debug.

I think my best thought right now is to add instrumentation down the call path to try to trace where the value is being created. At least this is happening at initialization, which should be more or less deterministic.

Thanks for your efforts!

@arlyon
Copy link

arlyon commented Jun 17, 2020

I'm getting a similar but equally opaque "Cannot determine default value of object" issue that comes from this line: https://github.com/software-mansion/react-native-reanimated/blob/master/src/core/AnimatedOperator.js#L76

I wish I had more information but the stack trace is useless. Same library though..

@mhorowitz
Copy link
Contributor

mhorowitz commented Jun 17, 2020

@arlyon Someone else reported that the version of the @babel/plugin-transform-classes plugin might be relevant here: #33 (comment)

Are you using this plugin, and which version of it are you using? Does changing it affect the behavior?

If you were willing to take the time to post a standalone JS file which fails, or even app which we could compile to reproduce the failure, then we could probably get to the bottom of this. Unfortunately, we don't yet have enough information to understand this bug.

@arlyon
Copy link

arlyon commented Jun 24, 2020

Hi, I am running 7.9.5 and will try out 7.8.x, but the issue appears intermittently so some more testing will be needed to confirm. Thanks for the tip.

@mhorowitz
Copy link
Contributor

mhorowitz commented Aug 4, 2020

@janicduplessis and others:

With the recent release of hermes 0.5.1 and 0.5.2-rc1 (Proxy opt-in), we are also now publishing unstripped libraries in the github releases which at long last give us the ability to symbolicate native crashes.

If you seen native crashes with Proxy in the past, please try to repro with RN 0.63 and Hermes 0.5.2-rc1. If you get a crash, please post it. You can also try to symbolicate it yourself using the instructions at https://github.com/facebook/hermes/blob/master/doc/ReactNativeIntegration.md#reporting-native-crashes

Thanks!

@janicduplessis
Copy link
Author

@mhorowitz I just tested 0.5.2-rc1 and the crash does not seem to happen anymore. I will keep further testing and report back if I get any crash.

@gigby
Copy link

gigby commented Dec 23, 2022

@mhorowitz Hi, I've got the same issue.

RN0.62.2
hermes (0.4.2-rc1)
react-native-navigation
react-native-reanimated

As you explained this issue comes with reanimated lib. But I notice interesting thing.
I have routing process like this:

  1. "initial screen" -> "page WITH NO imported reanimated" -> "page WITH imported reanimated"
  2. "initial screen" -> "page WITH imported reanimated"
    The second scenario crashes all the time I start the app but first one never does it.
    To prevent this bug I just import and use reanimated on the "initial screen" like this:
import Carousel from 'react-native-reanimated-carousel'; // this carousel uses reanimated lib
...
return(
<View>
...
  <View style={{ display: 'none' }}>
          <Carousel
              data={[1, 2]}
              renderItem={() => <Text>1</Text>}
              defaultIndex={1} width={400}
           />
   </View>
</View>
);

PS: I'm not sure that this way fixes this bug fully but it worked for me

@ibash
Copy link

ibash commented Apr 15, 2024

For posterity -- I found this bug in a library that was using proxies to return a http request. When trying to console.log the object object.name.toString() and object.name.valueOf() were being called, but a http request was returned instead. Fix is to explicitly check for toString/valueOf and to actually return a string.

ibash added a commit to ibash/hono that referenced this issue Apr 15, 2024
Fixes honojs#2509

When a hono client is instantiated in expo and then console.log(client)
is called, an error is thrown:

`TypeError: Cannot determine default value of object`

This is because the hermes javascript engine expects `new String(val)`
to always return a string. But the proxy object would return a
ClientRequestImpl object instead.

This commit makes a string / function returned in the cases where
.toString() and .valueOf() is called on the function.name or function
respectively.

Also see facebook/hermes#205
ibash added a commit to ibash/hono that referenced this issue Apr 15, 2024
Fixes honojs#2509

When a hono client is instantiated in expo and then console.log(client)
is called, an error is thrown:

`TypeError: Cannot determine default value of object`

This is because the hermes javascript engine expects `new String(val)`
to always return a string. But the proxy object would return a
ClientRequestImpl object instead.

This commit makes a string / function returned in the cases where
.toString() and .valueOf() is called on the function.name or function
respectively.

Also see facebook/hermes#205
ibash added a commit to ibash/hono that referenced this issue Apr 15, 2024
Fixes honojs#2509

When a hono client is instantiated in expo and then console.log(client)
is called, an error is thrown:

`TypeError: Cannot determine default value of object`

This is because the hermes javascript engine expects `new String(val)`
to always return a string. But the proxy object would return a
ClientRequestImpl object instead.

This commit makes a string / function returned in the cases where
.toString() and .valueOf() is called on the function.name or function
respectively.

Also see facebook/hermes#205
ibash added a commit to ibash/hono that referenced this issue Apr 17, 2024
Fixes honojs#2509

When a hono client is instantiated in expo and then console.log(client)
is called, an error is thrown:

`TypeError: Cannot determine default value of object`

This is because the hermes javascript engine expects `new String(val)`
to always return a string. But the proxy object would return a
ClientRequestImpl object instead.

This commit makes a string / function returned in the cases where
.toString() and .valueOf() is called on the function.name or function
respectively.

Also see facebook/hermes#205
yusukebe pushed a commit to honojs/hono that referenced this issue Apr 17, 2024
…2510)

Fixes #2509

When a hono client is instantiated in expo and then console.log(client)
is called, an error is thrown:

`TypeError: Cannot determine default value of object`

This is because the hermes javascript engine expects `new String(val)`
to always return a string. But the proxy object would return a
ClientRequestImpl object instead.

This commit makes a string / function returned in the cases where
.toString() and .valueOf() is called on the function.name or function
respectively.

Also see facebook/hermes#205
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
need more info Awating additional info before proceeding
Projects
None yet
Development

No branches or pull requests

5 participants