The embedded manifest is invalid or could not be read (EAS Build, Android)

  • Platform: Android
  • Workflow: Bare
  • CLI: eas-cli/0.54.1 darwin-arm64 node-v16.15.1

Hi, everyone.

I recently tried using eas build to build my Android app. Once it finished building, I downloaded it and uploaded it to the Google Play Console for Internal Testing use. The app runs fine on the Android emulator (running with yarn android, not the downloaded build), but on an actual device, it crashes, and I see the following:

FATAL EXCEPTION: main
java.lang.AssertionError: The embedded manifest is invalid or could not be read. Make sure you have configured expo-updates correctly in android/app/build.gradle. app.manifest
    at expo.modules.updates.manifest.EmbeddedManifest.get(EmbeddedManifest.kt:31)
    at expo.modules.updates.loader.LoaderTask.launchFallbackUpdateFromDisk(LoaderTask.kt:238)
    at expo.modules.updates.loader.LoaderTask.start(LoaderTask.kt:99)
    at expo.modules.updates.UpdatesController.start(UpdatesController.kt:290)
    at expo.modules.updates.UpdatesController$Companion.initialize(UpdatesController.kt:464)
    at expo.modules.updates.UpdatesPackage$createReactNativeHostHandlers$handler$1.onWillCreateReactInstanceManager(UpdatesPackage.kt:41)
    at expo.modules.ReactNativeHostWrapperBase.createReactInstanceManager(ReactNativeHostWrapperBase.kt:28)

...

As far as I can tell, expo-updates is set up correctly, but there’s some kind of issue.

For context, here’s my app.json:

{
  "name": "...",
  "displayName": "...",
  "expo": {
    "name": "...",
    "slug": "...",
    "version": "1.0.6",
    "description": "...",
    "jsEngine": "hermes",
    "privacy": "unlisted",
    "platforms": ["ios", "android"],
    "orientation": "portrait",
    "icon": "./assets/images/icon.png",
    "scheme": "...",
    "splash": {
      "image": "./assets/images/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#f9f9f9"
    },
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "userInterfaceStyle": "light",
    "assetBundlePatterns": ["**/*"],
    "ios": {
      "buildNumber": "215",
      "supportsTablet": false,
      "usesAppleSignIn": true,
      "infoPlist": {
        "LSApplicationQueriesSchemes": ["instagram", "twitter", "fb"]
      },
      "userInterfaceStyle": "light",
      "config": {
        "usesNonExemptEncryption": false,
        "googleSignIn": {
          "reservedClientId": "..."
        }
      },
      "bundleIdentifier": "..."
    },
    "hooks": {
      "postPublish": [
        {
          "file": "sentry-expo/upload-sourcemaps",
          "config": {
            "organization": "...",
            "project": "...",
            "authToken": "..."
          }
        }
      ]
    },
    "android": {
      "versionCode": 3,
      "userInterfaceStyle": "light"
    }
  }
}

Any advice on what I could try next? Thanks.

hey there! this is a good guide for troubleshooting issues: Troubleshooting build errors and crashes - Expo Documentation

it looks like you have a bare project but you are configuring your app with app.json? is that intentional that you have a bare app? (this means your ios and/or android directories exist in your project and are not ignored by source control)

Hi, @notbrent. Thanks for the reply! I’ll check out that troubleshooting documentation.

Regarding my app, I started with the managed workflow but had to eject to use In-App Purchases. Since then, I still have app.json, and my ios and android folders are committed. Maybe I missed something when ejecting (it was a while ago as this is a project I’ve been on and off for a couple of years). Is there something you suggest I do to my setup here? For context, my app is released on iOS, and I’m working to get Android ready now.

Regarding my original issue — with the build crashing on-device or in Test Lab, but not in the Android emulator — I’ve made some progress. I created a new project with expo init and compared some of the generated files with my project (running SDK 45). The only thing I noticed was that I was running a newer version of gradle:

My project:

classpath('com.android.tools.build:gradle:7.2.1')

New project

classpath('com.android.tools.build:gradle:7.0.4')

I downgraded to 7.0.4 and built the project again using eas build. After uploading that build for Internal Testing on Android, I didn’t get the Pre-launch report saying it had crashed with the issue shown in my original post. Instead, it said everything was okay. I’m yet to try on an actual device (I’ll do that tomorrow), but it seems like there was definitely progress there as the first 8 builds (on the newer gradle) had that error. As soon as I downgraded and built again, I didn’t get it.

Anyway, I hope that helps with understanding what was going on in my project. Thanks again for the reply and support — it’s much appreciated.

And for a little more context, here’s my AndroidManifest.xml. I haven’t touched this file at all until today, setting up In-App Purchases, when I added the BILLING permission. The rest was generated automatically.

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.app.name">
  <uses-permission android:name="android.permission.BILLING" />
  <uses-permission android:name="android.permission.INTERNET"/>
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
  <uses-permission android:name="android.permission.VIBRATE"/>
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  <queries>
    <intent>
      <action android:name="android.intent.action.VIEW"/>
      <category android:name="android.intent.category.BROWSABLE"/>
      <data android:scheme="https"/>
    </intent>
  </queries>
  <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:allowBackup="true" android:theme="@style/AppTheme" android:usesCleartextTraffic="true">
    <meta-data android:name="expo.modules.updates.ENABLED" android:value="true"/>
    <meta-data android:name="expo.modules.updates.EXPO_SDK_VERSION" android:value="45.0.0"/>
    <meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
    <meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
    <meta-data android:name="expo.modules.updates.EXPO_UPDATE_URL" android:value="https://exp.host/@user/app"/>
    <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode" android:launchMode="singleTask" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.App.SplashScreen" android:exported="true" android:screenOrientation="portrait">
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>
      <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:scheme="app"/>
        <data android:scheme="com.app.name"/>
      </intent-filter>
    </activity>
    <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false"/>
  </application>
</manifest>

if you’re not familiar with native android development, one thing you might want to consider is using revenuecat: Using RevenueCat with Expo's Managed Workflow

Hi, @notbrent. Yeah, I’ve heard about RevenueCat, and it looks great, but I already have expo-in-app-purchases working on iOS, so figured I should at least try to have it work on Android, too.

Regarding your earlier comment about app.json and having a bare project, does it sound like I have an issue with my setup? The original problem in this thread is now solved; I’m just curious about the question you asked.

Thanks again!

When you eject, you can no longer use app.json to e.g. set the splash screen or app icon, etc. You have to do that in the native projects.

@notbrent, is this still true?

This module is currently only available in the bare workflow.

The installation instructions look like it should work in a managed app with EAS build?

possibly - the truth is that nobody currently works on expo-iap (which is why we updated the docs page to say " Development of expo-in-app-purchases is currently paused, to focus on other projects .") and so i can’t say with certainty that it will or will not work

Oh, that’s a shame, especially after all the work having to eject so I could use the package. It’s also a little worrying after I just released my iOS app that relies on that package, and was planning on releasing the Android version (also using it) next month.

I see that the change to the documentation was made yesterday — was this something that was planned or was it a spontaneous decision? I can’t imagine Apple making any big changes to their API, but it’s a little concerning now that my whole IAP setup could suddenly become outdated if they do.

What would you recommend in my situation, @notbrent? My iOS app is live, and people have purchased subscriptions using my expo-in-app-purchases setup, and IAP is the last thing I need to test on Android before releasing in the coming weeks. It’s not ideal having to rock the boat and completely re-do IAP with one app live, but I’m open to suggestions as you have the best idea here. Thanks.

was this something that was planned or was it a spontaneous decision?

we were doing our quarterly planning and realized that we don’t have bandwidth on the team to maintain this at the moment. we can keep it working (provided no major changes are required), but there won’t be any active development or expand on any of the documented functionality.

if i were in your position i would migrate to using revenuecat. it shouldn’t be too difficult to migrate and you can count on them to support you if you run into any issues. this will also allow you to go back to managed workflow (just delete the ios and android directories)

Got it. Thanks, @notbrent. I appreciate the explanation.