Android app crashing on upgrade from SDK 34 to 37

Hi, we have an ExpoKit app that was previously SDK 34 that we’re upgrading to SDK 37. Most things are working fine, but once we’re out of dev and try testing upgrading, on Android the app keeps crashing. This can be fixed by clearing local storage; after that, the app runs fine.

This is the error from logcat:

java.lang.RuntimeException: Expo encountered a fatal error: 34.0.0 is not a valid SDK version. Options are 37.0.0, UNVERSIONED.
at host.exp.exponent.experience.BaseExperienceActivity.lambda$consumeErrorQueue$0$BaseExperienceActivity(BaseExperienceActivity.java:204)
at host.exp.exponent.experience.-$$Lambda$BaseExperienceActivity$zZZNiLUhJmY4AlwF2loJATXcbqc.run(Unknown Source:2)
at android.app.Activity.runOnUiThread(Activity.java:6404)
at host.exp.exponent.experience.BaseExperienceActivity.consumeErrorQueue(BaseExperienceActivity.java:184)
at host.exp.exponent.experience.BaseExperienceActivity.addError(BaseExperienceActivity.java:73)
at host.exp.exponent.kernel.Kernel.handleReactNativeError(Kernel.java:1051)
at host.exp.exponent.kernel.Kernel.handleError(Kernel.java:1056)
at host.exp.exponent.experience.ExperienceActivity.setManifest(ExperienceActivity.java:418)
at host.exp.exponent.experience.ExperienceActivity$2$2.run(ExperienceActivity.java:221)
at host.exp.expoview.Exponent.runOnUiThread(Exponent.java:218)
at host.exp.exponent.experience.ExperienceActivity$2.onManifestCompleted(ExperienceActivity.java:215)
at host.exp.exponent.AppLoader.resolve(AppLoader.java:240)
at host.exp.exponent.AppLoader.resolve(AppLoader.java:215)
at host.exp.exponent.AppLoader.access$000(AppLoader.java:20)
at host.exp.exponent.AppLoader$5.onBundleLoaded(AppLoader.java:337)
at host.exp.expoview.Exponent$2$1.run(Exponent.java:452)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7073)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)

My understanding is that this means the app is trying to run our old SDK-34-versioned JS bundle instead of the SDK 37 one it was built with (and that should have also been published). Once we clear the cached version by clearing internal storage, it pulls in the right version.

Since we’re not 100% sure of the cause, we’ve tried a few things that didn’t help:

  1. created a new release channel to make sure it was not serving older versions (and did this for each following change)
  2. updated the kernel-manifest.json file in the android directory to match the expo repo’s sdk-37 branch since that wasn’t auto-updated
  3. re-added sdkVersion: "37.0.0" to the app.json, since the expo upgrade tool removed that line
  4. verified that the expo package has a version of 37+ in its package.json, and that version 34 was not mentioned anywhere else in our repo

We focused on the sdkVersion in the manifests since that seems to be where this error originates: https://github.com/expo/expo/blob/sdk-37/android/expoview/src/main/java/host/exp/exponent/experience/ExperienceActivity.java#L429

Our app uses updates.checkAutomatically: 'ON_ERROR_RECOVERY' to control when users get updates. Next up we’re experimenting with changing that to see if we can get the app to maybe re-download a correctly-versioned JS bundle.

Does anyone have advice to help us figure out how this should be working? By everything I can read, the app should be using the JS bundle it’s built with, or at least only download the newly-versioned-for-SDK-37 JS bundle we published.

Some updates after further troubleshooting:

  • We found that changing the value of “checkAutomatically” did not have any impact on the crash
  • via some logging debugging, we’re finding that our JS code never runs before the crash, so we’re reasonably confident this is a configuration and/or ExpoKit issue
  • We checked the publish:history for our app and saw the most recent JS bundles did indeed have an sdkVersion of “37.0.0”.

Our next line of thinking is that it’s possible the release channel configuration isn’t getting picked up properly and it’s using an old release channel, so we’ll be trying to debug whether that’s the case in the Java code next.

However, it still seems more likely that the app is using an old cached version of the bundle in local storage rather than the one it was shipped with, so we’re looking into that too.

@esamelson - any ideas about this?

We found what was causing this today – it was a bit of a misconfiguration issue.

I had tried to clean up the generated expokit files from the git worktree, and we scripted adding them back when needed. However, because we didn’t understand when all of the pieces of the files were generated, we got the ordering wrong.

We needed to lay down the generated files before running expo publish. Since we didn’t, some “EmbeddedResponses” didn’t get added to AppConstants.java (this appears to happen in the expo publish step, but it will not error if the file is missing), which apparently results in our embedded manifest not getting used.