App crashes with Reflect.construct.apply error during Purchases SDK log handler setup (Expo 54, RN 0.81.4, React 19)
Checklist:
- I have updated Purchases SDK to the latest version (9.5.1)
- I have read the https://github.com/RevenueCat/react-native-purchases/blob/main/CONTRIBUTING.md
- I have searched the https://community.revenuecat.com
- I have read https://docs.revenuecat.com/
- I have searched for https://github.com/RevenueCat/react-native-purchases/issues
Describe the bug
The app crashes immediately on launch with a Reflect.construct error originating from the Purchases SDK's error logging mechanism. The crash occurs when the SDK attempts to set up its log handler, specifically when creating a custom error class for stack trace capture.
- Environment a. Platform: iOS (development simulator) b. SDK version: [email protected] c. OS version: macOS Darwin 24.6.0 (iOS Simulator) d. Xcode/Android Studio version: Xcode (version TBD based on macOS 24.6.0) e. React Native version: 0.81.4 f. SDK installation: Package manager (pnpm 10.12.3) g. How widespread is the issue: 100% of launches in development environment h. IOS: 26.0.1
- Debug logs that reproduce the issue
Code: construct.js
2 | var setPrototypeOf = require("./setPrototypeOf.js");
3 | function _construct(t, e, r) {
> 4 | if (isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments);
| ^
5 | var o = [null];
6 | o.push.apply(o, e);
7 | var p = new (t.bind.apply(t, o))();
Call Stack:
construct (apps/mobile/<native>)
apply (apps/mobile/<native>)
_construct
(node_modules/.pnpm/@[email protected]/node_modules/@babel/runtime/helpers/construct.js:4:65)
Wrapper
(node_modules/.pnpm/@[email protected]/node_modules/@babel/runtime/helpers/wrapNativeSuper.js:15:23)
construct (apps/mobile/<native>)
_callSuper
(node_modules/.pnpm/@[email protected]/node_modules/@babel/runtime/helpers/callSuper.js:5:108)
NamelessError (node_modules/.pnpm/@[email protected][email protected][email protected]_react-native@
[email protected]/node_modules/@expo/metro-runtime/src/metroServerLogs.native.ts:102:20)
captureCurrentStack (node_modules/.pnpm/@[email protected][email protected][email protected]_react-n
[email protected][email protected]/node_modules/@expo/metro-runtime/src/metroServerLogs.native.ts:106:27)
HMRClient.log (node_modules/.pnpm/@[email protected][email protected][email protected]_react-native@
[email protected]/node_modules/@expo/metro-runtime/src/metroServerLogs.native.ts:39:79)
console.level (node_modules/.pnpm/[email protected]_@[email protected]_@[email protected]_react@19.
1.0/node_modules/react-native/Libraries/Core/setUpDeveloperTools.js:41:24)
setLogHandler$argument_0 (node_modules/.pnpm/[email protected][email protected]_react
[email protected][email protected]/node_modules/react-native-purchases/dist/purchases.js:114:38)
eventEmitter.addListener$argument_1 (node_modules/.pnpm/[email protected]_react-native-web@0
[email protected][email protected]/node_modules/react-native-purchases/dist/purchases.js:72:21)
- Steps to reproduce - Install [email protected] in an Expo 54.0.11 project with React Native 0.81.4 - Import and initialize the Purchases SDK - Launch the app in development mode with Expo Metro bundler - Expected behavior: App launches successfully with Purchases SDK initialized - Actual behavior: App crashes immediately with Reflect.construct error during SDK initialization
- Other information
- The error originates from purchases.js:114:38 when setting up the log handler
- This appears to be related to Babel runtime helpers (@babel/[email protected]) and how the SDK creates
custom error classes for logging
- The crash happens before any SDK methods are called, suggesting it's an initialization/setup issue
- Environment: Expo 54.0.11, React 19.1.0, React Native 0.81.4
- Package manager: pnpm 10.12.3
- Node.js: v22.19.0
- The issue may be related to the interaction between:
- Expo Metro runtime's error capturing mechanism
- react-native-purchases' custom error logging
- Babel's native super class wrapping helpers - This appears to be a compatibility issue with the newer Expo/React Native/React versions
Additional context This is a monorepo project using Turborepo. The mobile app is an Expo-managed workflow project. The error prevents the SDK from initializing entirely, making the app unusable in development.
👀 We've just linked this issue to our internal tracker and notified the team. Thank you for reporting, we're checking this out!
@yahavf6 Thanks for reporting 🙏 The team is looking into now and we will hit you up if we have any further questions!
I am experiencing the same issue.
Code: construct.js
2 | var setPrototypeOf = require("./setPrototypeOf.js");
3 | function _construct(t, e, r) {
> 4 | if (isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments);
| ^
5 | var o = [null];
6 | o.push.apply(o, e);
7 | var p = new (t.bind.apply(t, o))();
Call Stack
construct (<native>)
apply (<native>)
_construct (node_modules/@babel/runtime/helpers/construct.js:4:65)
Wrapper (node_modules/@babel/runtime/helpers/wrapNativeSuper.js:15:23)
construct (<native>)
_callSuper (node_modules/@babel/runtime/helpers/callSuper.js:5:108)
NamelessError (node_modules/@expo/metro-runtime/src/metroServerLogs.native.ts:102:20)
captureCurrentStack (node_modules/@expo/metro-runtime/src/metroServerLogs.native.ts:106:27)
HMRClient.log (node_modules/@expo/metro-runtime/src/metroServerLogs.native.ts:39:79)
console.level (node_modules/react-native/Libraries/Core/setUpDeveloperTools.js:41:24)
apply (<native>)
i (node_modules/@logrocket/react-native/dist/build.js:1:100406)
setLogHandler$argument_0 (node_modules/react-native-purchases/dist/purchases.js:114:38)
eventEmitter.addListener$argument_1 (node_modules/react-native-purchases/dist/purchases.js:72:21)
apply (<native>)
emit (node_modules/react-native/Libraries/vendor/emitter/EventEmitter.js:130:36)
apply (<native>)
<anonymous> (node_modules/@babel/runtime/helpers/superPropGet.js:6:19)
RCTDeviceEventEmitterImpl#emit (node_modules/react-native/Libraries/EventEmitter/RCTDeviceEventEmitter.js:33:5)
- Environment: Expo 54.0.10, React 19.1.0, React Native 0.81.4
- Package manager: [email protected]
- Node.js: [email protected]
Although I believe the specific error code location is not related to this problem.
Code: construct.js
2 | var setPrototypeOf = require("./setPrototypeOf.js");
3 | function _construct(t, e, r) {
> 4 | if (isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments);
| ^
5 | var o = [null];
6 | o.push.apply(o, e);
7 | var p = new (t.bind.apply(t, o))();
After temporarily disabling the Purchases SDK. For an unrelated different error in my app, I get the same code location strace. I am not fully understanding this yet, but I expect this "code location trace"-issue to be some quirk with the latest version of Expo/React native?
ERROR Cannot set prop 'borderRadius' on view 'class expo.modules.image.ExpoImageViewWrapper'
→ Caused by: com.facebook.react.bridge.UnexpectedNativeTypeException: Value for borderRadius cannot be cast from String to double
Code: construct.js
2 | var setPrototypeOf = require("./setPrototypeOf.js");
3 | function _construct(t, e, r) {
> 4 | if (isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments);
| ^
5 | var o = [null];
6 | o.push.apply(o, e);
7 | var p = new (t.bind.apply(t, o))();
Call Stack
construct (<native>)
apply (<native>)
_construct (node_modules/@babel/runtime/helpers/construct.js:4:65)
Wrapper (node_modules/@babel/runtime/helpers/wrapNativeSuper.js:15:23)
construct (<native>)
_callSuper (node_modules/@babel/runtime/helpers/callSuper.js:5:108)
NamelessError (node_modules/@expo/metro-runtime/src/metroServerLogs.native.ts:102:20)
captureCurrentStack (node_modules/@expo/metro-runtime/src/metroServerLogs.native.ts:106:27)
HMRClient.log (node_modules/@expo/metro-runtime/src/metroServerLogs.native.ts:39:79)
console.level (node_modules/react-native/Libraries/Core/setUpDeveloperTools.js:41:24)
NativeJSLogger.addListener$argument_1 (node_modules/expo-modules-core/src/sweet/setUpJsLogger.fx.ts:46:22)
I am experiencing the same issue.
Code: construct.js 2 | var setPrototypeOf = require("./setPrototypeOf.js"); 3 | function _construct(t, e, r) { > 4 | if (isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments); | ^ 5 | var o = [null]; 6 | o.push.apply(o, e); 7 | var p = new (t.bind.apply(t, o))(); Call Stack construct (<native>) apply (<native>) _construct (node_modules/@babel/runtime/helpers/construct.js:4:65) Wrapper (node_modules/@babel/runtime/helpers/wrapNativeSuper.js:15:23) construct (<native>) _callSuper (node_modules/@babel/runtime/helpers/callSuper.js:5:108) NamelessError (node_modules/@expo/metro-runtime/src/metroServerLogs.native.ts:102:20) captureCurrentStack (node_modules/@expo/metro-runtime/src/metroServerLogs.native.ts:106:27) HMRClient.log (node_modules/@expo/metro-runtime/src/metroServerLogs.native.ts:39:79) console.level (node_modules/react-native/Libraries/Core/setUpDeveloperTools.js:41:24) apply (<native>) i (node_modules/@logrocket/react-native/dist/build.js:1:100406) setLogHandler$argument_0 (node_modules/react-native-purchases/dist/purchases.js:114:38) eventEmitter.addListener$argument_1 (node_modules/react-native-purchases/dist/purchases.js:72:21) apply (<native>) emit (node_modules/react-native/Libraries/vendor/emitter/EventEmitter.js:130:36) apply (<native>) <anonymous> (node_modules/@babel/runtime/helpers/superPropGet.js:6:19) RCTDeviceEventEmitterImpl#emit (node_modules/react-native/Libraries/EventEmitter/RCTDeviceEventEmitter.js:33:5)
- Environment: Expo 54.0.10, React 19.1.0, React Native 0.81.4
- Package manager: [email protected]
- Node.js: [email protected]
Although I believe the specific error code location is not related to this problem.
Code: construct.js 2 | var setPrototypeOf = require("./setPrototypeOf.js"); 3 | function _construct(t, e, r) { > 4 | if (isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments); | ^ 5 | var o = [null]; 6 | o.push.apply(o, e); 7 | var p = new (t.bind.apply(t, o))();After temporarily disabling the Purchases SDK. For an unrelated different error in my app, I get the same code location strace. I am not fully understanding this yet, but I expect this "code location trace"-issue to be some quirk with the latest version of Expo/React native?
ERROR Cannot set prop 'borderRadius' on view 'class expo.modules.image.ExpoImageViewWrapper' → Caused by: com.facebook.react.bridge.UnexpectedNativeTypeException: Value for borderRadius cannot be cast from String to double Code: construct.js 2 | var setPrototypeOf = require("./setPrototypeOf.js"); 3 | function _construct(t, e, r) { > 4 | if (isNativeReflectConstruct()) return Reflect.construct.apply(null, arguments); | ^ 5 | var o = [null]; 6 | o.push.apply(o, e); 7 | var p = new (t.bind.apply(t, o))(); Call Stack construct (<native>) apply (<native>) _construct (node_modules/@babel/runtime/helpers/construct.js:4:65) Wrapper (node_modules/@babel/runtime/helpers/wrapNativeSuper.js:15:23) construct (<native>) _callSuper (node_modules/@babel/runtime/helpers/callSuper.js:5:108) NamelessError (node_modules/@expo/metro-runtime/src/metroServerLogs.native.ts:102:20) captureCurrentStack (node_modules/@expo/metro-runtime/src/metroServerLogs.native.ts:106:27) HMRClient.log (node_modules/@expo/metro-runtime/src/metroServerLogs.native.ts:39:79) console.level (node_modules/react-native/Libraries/Core/setUpDeveloperTools.js:41:24) NativeJSLogger.addListener$argument_1 (node_modules/expo-modules-core/src/sweet/setUpJsLogger.fx.ts:46:22)
same here