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

RN 0.60.5 app on iOS crashes on startup: "RCTFatalException: Unhandled JS Exception: Native module cannot be null" #26119

Closed
sunweiyang opened this issue Aug 20, 2019 · 29 comments
Labels
Bug Platform: iOS iOS applications. Stale There has been a lack of activity on this issue and it may be closed soon.

Comments

@sunweiyang
Copy link
Contributor

sunweiyang commented Aug 20, 2019

I'm trying to update my RN from 0.59.5 to 0.60.5. I was able to get Android app to work fine, but the same app on iOS (whose build completes successfully otherwise) crashes on cold app start with an RCTFatalException: Unhandled JS Exception: Native module cannot be null error, right after the splash screen disappears. The Metro bundler doesn't show any communication from the simulator/device; when the iOS app launches and crashes, the Metro bunder terminal output is unchanged.

This happens for both iOS Simulator and for real iOS devices running iOS 12.4 (iPhone SE, iPhone 8, and iPad 3rd generation).

Relevant facts:

  • App worked perfectly fine for both iOS and Android when on 0.59.5
  • With 0.60.5, app now only works for Android
  • I used rn-diff-purge to update manually (via https://react-native-community.github.io/upgrade-helper/)
  • I have added the missing Start Packager Build Script (from Packager not starting after 0.59 to 0.60 migration  #25585)
  • My Metro bundler is on in a separate terminal window, using port 8081, registering no changes when the app launches on an iOS device/simulator
  • I confirm that I still have the localhost exception in my Info.plist file
  • I have separate index.android.js and index.ios.js files, but don't believe this should have made a difference (please correct me if I'm wrong). My AppDelegate.m contains the following sourceURLForBridge method (it uses CodePush when building the app for non-debug app, but this issue is purely for debug app):
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
#else
  return [CodePush bundleURL];
#endif
}

Relevant Xcode debug output:

2019-08-19 16:54:48.466 [error][tid:com.facebook.react.JavaScript] Native module cannot be null.
2019-08-19 16:54:48.469051-0700 Skale[29480:811282] Native module cannot be null.
2019-08-19 16:54:48.473 [fatal][tid:com.facebook.react.ExceptionsManagerQueue] Unhandled JS Exception: Native module cannot be null.
2019-08-19 16:54:48.473052-0700 Skale[29480:811179] Unhandled JS Exception: Native module cannot be null.
2019-08-19 16:54:48.473 [error][tid:com.facebook.react.JavaScript] Module AppRegistry is not a registered callable module (calling runApplication)
2019-08-19 16:54:48.473480-0700 Skale[29480:811282] Module AppRegistry is not a registered callable module (calling runApplication)
2019-08-19 16:54:48.497285-0700 Skale[29480:811179] *** Terminating app due to uncaught exception 'RCTFatalException: Unhandled JS Exception: Native module cannot be null.', reason: 'Unhandled JS Exception: Native module cannot be null., stack:
_@115:244
<unknown>@972:266
v@2:1474
<unknown>@971:241
v@2:1474
<unknown>@970:531
v@2:1474
<unknown>@968:269
v@2:1474
<unknown>@389:345
v@2:1474
<unknown>@388:98
v@2:1474
<unknown>@383:177
v@2:1474
<unknown>@370:340
v@2:1474
<unknown>@6:251
v@2:1474
d@2:876
global code@1030:4
'
*** First throw call stack:
(
	0   CoreFoundation                      0x00000001119508db __exceptionPreprocess + 331
	1   libobjc.A.dylib                     0x0000000114998ac5 objc_exception_throw + 48
	2   Skale                               0x000000010efb6a7c RCTGetFatalHandler + 0
	3   Skale                               0x000000010efd9b4c -[RCTExceptionsManager reportFatalException:stack:exceptionId:] + 507
	4   CoreFoundation                      0x00000001119576ac __invoking___ + 140
	5   CoreFoundation                      0x0000000111954c25 -[NSInvocation invoke] + 325
	6   CoreFoundation                      0x0000000111955076 -[NSInvocation invokeWithTarget:] + 54
	7   Skale                               0x000000010efec84a -[RCTModuleMethod invokeWithBridge:module:arguments:] + 602
	8   Skale                               0x000000010efeec9d _ZN8facebook5reactL11invokeInnerEP9RCTBridgeP13RCTModuleDatajRKN5folly7dynamicE + 251
	9   Skale                               0x000000010efeea1f ___ZN8facebook5react15RCTNativeModule6invokeEjON5folly7dynamicEi_block_invoke + 78
	10  libdispatch.dylib                   0x0000000116d28d7f _dispatch_call_block_and_release + 12
	11  libdispatch.dylib                   0x0000000116d29db5 _dispatch_client_callout + 8
	12  libdispatch.dylib                   0x0000000116d31225 _dispatch_lane_serial_drain + 778
	13  libdispatch.dylib                   0x0000000116d31e9c _dispatch_lane_invoke + 425
	14  libdispatch.dylib                   0x0000000116d3bea3 _dispatch_workloop_worker_thread + 733
	15  libsystem_pthread.dylib             0x00000001186b1611 _pthread_wqthread + 421
	16  libsystem_pthread.dylib             0x00000001186b13fd start_wqthread + 13
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

React Native version:

System:
OS: macOS 10.14.6
CPU: (8) x64 Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz
Memory: 24.93 MB / 16.00 GB
Shell: 5.6.2 - /usr/local/bin/zsh
Binaries:
Node: 10.16.2 - /usr/local/bin/node
Yarn: 1.7.0 - /usr/local/bin/yarn
npm: 6.9.0 - /usr/local/bin/npm
Watchman: 4.9.4 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 12.4, macOS 10.14, tvOS 12.4, watchOS 5.3
Android SDK:
API Levels: 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29
Build Tools: 23.0.1, 23.0.2, 23.0.3, 24.0.0, 24.0.1, 24.0.2, 24.0.3, 25.0.0, 25.0.1, 25.0.2, 25.0.3, 26.0.0, 26.0.1, 26.0.2, 26.0.3, 27.0.0, 27.0.1, 27.0.2, 27.0.3, 28.0.0, 28.0.0, 28.0.3, 29.0.0, 29.0.1
System Images: android-16 | Intel x86 Atom, android-16 | Google APIs Intel x86 Atom, android-17 | Google APIs Intel x86 Atom, android-18 | Google APIs Intel x86 Atom, android-19 | Google APIs Intel x86 Atom, android-21 | Google APIs Intel x86 Atom, android-22 | Google APIs Intel x86 Atom, android-23 | Google APIs Intel x86 Atom, android-24 | Google APIs Intel x86 Atom, android-25 | Google APIs Intel x86 Atom, android-26 | Google APIs Intel x86 Atom, android-26 | Google APIs Intel x86 Atom_64, android-27 | Google APIs Intel x86 Atom, android-27 | Google Play Intel x86 Atom, android-28 | Google APIs Intel x86 Atom, android-29 | Google APIs Intel x86 Atom
IDEs:
Android Studio: 3.4 AI-183.6156.11.34.5692245
Xcode: 10.3/10G8 - /usr/bin/xcodebuild
npmPackages:
react: 16.8.6 => 16.8.6
react-native: 0.60.5 => 0.60.5
npmGlobalPackages:
create-react-native-app: 1.0.0
react-native-cli: 2.0.1
react-native-git-upgrade: 0.2.7
react-native-rename: 2.2.2

Steps To Reproduce

  1. Use changes prescribed by rn-diff-purge (https://react-native-community.github.io/upgrade-helper/) to manually update an existing working RN 0.59.5 app's codebase
  2. Add missing Start Packager script in app's Xcode Build Phases (from Packager not starting after 0.59 to 0.60 migration  #25585)
  3. Build using either react-native run-ios or through opening the .xcworkspace file and clicking the build ("run") button; observe successful build
  4. Launch the app and observe crash in Xcode debugger: RCTFatalException: Unhandled JS Exception: Native module cannot be null
@sunweiyang sunweiyang added the Bug label Aug 20, 2019
@react-native-bot react-native-bot added the Platform: iOS iOS applications. label Aug 20, 2019
@ckOfor
Copy link

ckOfor commented Aug 20, 2019

@sunweiyang I have this same problem, any luck?

@janet-rivas
Copy link

@sunweiyang the same issue, I'll downgrade to RN lower version and see if there is any luck

ExceptionsManager.js:86 Module AppRegistry is not a registered callable module (calling runApplication)
handleException @ ExceptionsManager.js:86
handleError @ setUpErrorHandling.js:23
reportFatalError @ error-guard.js:42
__guard @ MessageQueue.js:345
callFunctionReturnFlushedQueue @ MessageQueue.js:105
(anonymous) @ debuggerWorker.js:80
ExceptionsManager.js:94 Unhandled JS Exception: Native module cannot be null.

reactConsoleErrorHandler @ ExceptionsManager.js:94
logToConsole @ RCTLog.js:47
logIfNoNativeHook @ RCTLog.js:30
__callFunction @ MessageQueue.js:395
(anonymous) @ MessageQueue.js:106
__guard @ MessageQueue.js:343
callFunctionReturnFlushedQueue @ MessageQueue.js:105
(anonymous) @ debuggerWorker.js:80
ExceptionsManager.js:94 Unhandled JS Exception: Module AppRegistry is not a registered callable module (calling runApplication)
Screen Shot 2019-08-20 at 4 39 48 PM

@sunweiyang
Copy link
Contributor Author

@ckOfor No luck yet.
My issue is somewhat different from that of @janet-rivas -- my app doesn't even display that screen. The crash happens right after my splash screen goes away and just shows the default background color.

@janet-rivas
Copy link

yes seems like it's different I'll open a new bug, Thank you!!

@ckOfor
Copy link

ckOfor commented Aug 20, 2019

@sunweiyang :( Mine too crashes after splash screen

@oknechirik
Copy link

Have the same issue
Nothing helps

@emision
Copy link

emision commented Aug 21, 2019

Have same issue

@deepslam
Copy link

Any news here?

@ckOfor
Copy link

ckOfor commented Aug 22, 2019

@sunweiyang I finally found a fix for mine which was similar to yours

AppRegistry is not a registered callable module

Add this to the bottom of your entry file

AppRegistry.registerComponent("AppName", () => LandingPage)

@ckOfor
Copy link

ckOfor commented Aug 22, 2019

However, mine was App is not registered so I guess yours has something to do with AppRegistry

@sunweiyang
Copy link
Contributor Author

@ckOfor Glad to see that you got yours to work! I do have that line in my entry file, so unfortunately I'm still stuck.

@sunweiyang
Copy link
Contributor Author

@oknechirik @emision @deepslam I'm curious, are any of you also using CodePush? Wondering if it's related.

@willysama
Copy link

Not using it and I've got the very same issue than yours. Fine on Android, crash on iOS

@willysama
Copy link

willysama commented Aug 23, 2019

I fixed it. I had the error du to react-native-reanimated. I linked it with react-native link. Then I got the same error but on another module.
So I think that it is due to linking on iOS. Based on Upgrade diff from 0.59.10 to 0.60.5, it seems linking is managed by Podfile now on iOS. I'm gonna use it and see how it goes.

EDIT: I confirm that it works after setting CocoaPods up! Copy the Podfile from the upgrade link above. then you this quick guide. And open and build from your [project_name].xcworkspace and you should be good to go!

@ckOfor
Copy link

ckOfor commented Aug 23, 2019

@sunweiyang can you share your pod file?

@ckOfor
Copy link

ckOfor commented Aug 23, 2019

I finally got mine working by

  1. Upgrading the rn to 0.60.5
  2. Manually linking react-native-screens (optional if you are using it) for Android it as a dependency and also in the settings.gradle file
  3. Deleting podfile lock
  4. Editing podfile
 pod 'React', :path => '../node_modules/react-native/'
  pod 'React-Core', :path => '../node_modules/react-native/React'
  pod 'React-DevSupport', :path => '../node_modules/react-native/React'
  # pod 'React-fishhook', :path => '../node_modules/react-native/Libraries/fishhook'
  pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
  pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
  pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
  pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
  pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
  pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
  pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
  pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
  pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
  pod 'React-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket'

  pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
  pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
  pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
  pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
  pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'

  pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
  pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
  pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
  pod 'RNGestureHandler', :podspec => '../node_modules/react-native-gesture-handler/RNGestureHandler.podspec'
  pod 'RNReanimated', :podspec => '../node_modules/react-native-reanimated/RNReanimated.podspec'
  pod 'RNScreens', :path => '../node_modules/react-native-screens'

@ckOfor
Copy link

ckOfor commented Aug 23, 2019

For linking RNScreen manually

  • MainApplication.java
  1. import com.swmansion.rnscreens.RNScreensPackage;
  2. new RNScreensPackage(),
  • settings.gradle
    include ':react-native-screens' project(':react-native-screens').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-screens/android')

  • app/build.gradle
    implementation project(':react-native-reanimated')

@sunweiyang
Copy link
Contributor Author

sunweiyang commented Aug 28, 2019

All right, I have made a small step in the right direction.

I was using react-native-schemes-manager when my app was on 0.59.5, but according to this helpful comment, this package is no longer necessary in 0.60.x.

I've made the following changes:

  • Modified my Podfile using the comment mentioned above
  • Changed the Bundle React Native code and images script in Build Phases back to the default
  • Removed lines from package.json that were required by react-native-schemes-manager such as xcodeSchemes and postInstall scripts (see here)
  • Removed the react-native-schemes-manager package

There was an improvement! At least now my app can contact the Metro bundler and get a JS bundle.

I'm now in the exact same situation as @janet-rivas (red screen warning for "Native module cannot be null").
@janet-rivas were you able to make any progress?

@edcs
Copy link
Contributor

edcs commented Sep 5, 2019

I'm having the same issue - I removed react-native-schemes-manager as suggested by @sunweiyang but haven't got any further. I think the error message is misleading, it suggests that there's something wrong with AppRegistry. However I think that the issue is possible because of an issue with a 3rd party package. I'm using react-native-device-info (amongst others) and when I remove calls to that package in my index.js the app loads my App.js (which means that AppRegistry.registerComponent(name, () => App) is working).

This issue seems to only affect iOS, my Android build seems to be working as expected.

@edcs
Copy link
Contributor

edcs commented Sep 5, 2019

This problem is a bit tricky to debug, but it was due to an incompatible package. I'm also using react-native-push-notification which didn't seem to work correctly for me. The Native module cannot be null error arises from the constructor in node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter.js.

To debug which module was causing issues, I modified the constructor with the following patch (you could use a code break if you wanted, this is a quick and dirty hack):

if (Platform.OS === 'ios') {
+  if (!nativeModule) {
+    console.trace()
+  }
  invariant(nativeModule, 'Native module cannot be null.');
  this._nativeModule = nativeModule;
}

Then when you run your app, it will print the stack trace allowing you to see where the error is coming from:

image

You can then click through to your component and see which module caused the invariant:

image

I've not quite figured out a fix for this yet, I'll update this issue when I know what's going on.

@edcs
Copy link
Contributor

edcs commented Sep 5, 2019

Another update, my issue was caused by the push notification package I'm using switching from the bundled iOS push notification handler to @react-native-community/react-native-push-notification-ios. I needed to follow the documentation to install it and remove my own usages of RCTPushNotificationManager:

https://github.com/react-native-community/react-native-push-notification-ios

This might not be what your specific issue is, but I think the same debugging technique will work for other projects with strange native module issues. Another thing that I found quite useful was to dump the list of loaded native modules like so:

import { NativeModules } from 'react-native';

console.log(NativeModules);

That way you can see if anything you're expecting to be loaded is missing.

@sunweiyang
Copy link
Contributor Author

sunweiyang commented Sep 5, 2019

I have just recently solved my issue. As mentioned by @edcs, it was indeed due to a third-party package (in this case it was opentok-react-native).

For anyone experiencing this problem (@janet-rivas, etc.), I'm afraid the only solution is to methodically audit your third-party packages, one by one.

It was good that I caught this, because opentok-react-native was also causing other unrelated issues for Android too. My fix was ultimately to manually link the problematic package (taking care to handle the new MainApplication.java package listing format for RN 0.60x on the Android side of things), and to update react-native.config.js as follows:

 module.exports = {
  dependencies: {
    "opentok-react-native": {
      platforms: {
        ios: null,
        android: null
      }
    }
  }
};

My app is now fully working on both platforms!

@developerashish01
Copy link

I am facing same issue. any luck there?

@MounirDhahri
Copy link

Please run react-native run-ios. The build will fail and give you a list of package that you will need to unlink. react-native unlink ..... After unlinking all mentioned libraries, xCode will be back to working again. (at least this was the solution for me)

@jbustard
Copy link

jbustard commented Oct 4, 2019

I am also seeing this issue on react-native 0.60.5. Using the technique posted by @edcs, I got a stack trace pointing to a component within my app, which in turn appears to be linked to the redux-store. This would appear to implicate the redux-persist lib in my case, but I am still investigating. Any other feedback would be welcome!

@MounirDhahri I tried what you suggested, but unlinking everything won't work because some of the libs I am using still do not support autolinking. Also, anything I do to iOS has knock on effects to Android, which is working as intended. My failure is only on iOS. This has to be an issue with an iOS implementation of some library specifically.

@suhask-iprogrammer
Copy link

any update on this issue?

@dominiczaq
Copy link

Not sure it it's the right place to ask but shouldn't the types for NativeEventEmitter.js be updated to require nativeModule in the constructor?

Currently there is:

  constructor(nativeModule: ?NativeModule) {
    super(RCTDeviceEventEmitter.sharedSubscriber);
    if (Platform.OS === 'ios') {
      invariant(nativeModule, 'Native module cannot be null.');
      this._nativeModule = nativeModule;
    }
  }

The invariant for 'ios' clearly implies that even though the type specifies nativeModule as optional, the exception will be thrown if nativeModule is null/undefined.
As this code is shared between android and ios (and android runs without any error when the nativeModule is ommited) I think the types should mark nativeModule as required.

@stale
Copy link

stale bot commented Feb 10, 2020

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Feb 10, 2020
@stale
Copy link

stale bot commented Feb 17, 2020

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.

@stale stale bot closed this as completed Feb 17, 2020
@facebook facebook locked as resolved and limited conversation to collaborators Feb 18, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Bug Platform: iOS iOS applications. Stale There has been a lack of activity on this issue and it may be closed soon.
Projects
None yet
Development

No branches or pull requests