Skip to content

Can't install update on Expo app with new architecture on Android #35

Open

Description

@d-laskowski-trojmiasto

I have latest Expo (57) with latest version of this lib and enabled new architecture and I'm currently testing on Android but eventually I need to have this working also on iOS. I'm also using EAS Build. I tried everything and every time app crashes after installing update and rolls back to previous version. Cloude found several problems like including CodePush in wrong place in MainApplication.kt, wrong file path for JS bundle but all of these fixes don't eventually work. Please let somebody verify if this lib works with latest Expo because amount of problems I have make me suspect the lib is broken.

Activity

  1. ofalvai commented on Aug 18, 2026

    @ofalvai
    Collaborator

    We are testing the project against Expo 57 since #13

    If you have specific crash logs or any other information which would help in debugging this, please share, and we'll take a look.

  2. d-laskowski-trojmiasto commented on Aug 18, 2026

    @d-laskowski-trojmiasto
    Author

    Prebuild prints

    » android: codepush-plugin: SoLoader.init() not found in onCreate(). Placing CodePush initialization after super.onCreate().
    

    Cloude made me config plugin to fix it.
    Then log from update with the plugin

    08-18 08:47:50.928 14002 14215 E ReactNativeJS: { [Error: Exception in HostFunction: java.net.MalformedURLException: no protocol: /data/user/0/pl.trojmiasto.mobile/files/CodePush/ecdc803ce3df676278ff1722b26d0e8182bf8f6a5dc1361b34ee57b67bf7b69b/build/index.android.bundle]
    

    Cloude made me another plugin to fix JS bundle path (adding file:// prefix) but it still crashes

    08-18 11:25:39.184 31787 31787 W unknown:BridgelessReact: ReactHost{0}.handleHostException(message = "JSBigFileString::fromPath - Could not open file: file:///data/user/0/pl.trojmiasto.mobile/files/CodePush/c8e3ab71e0bf0290159abe04ce06ef1f8467aad5c07f5085fdc803cdd5afa67d/build/index.android.bundle")
    08-18 11:25:39.184 31787 31787 E AndroidRuntime: java.lang.RuntimeException: JSBigFileString::fromPath - Could not open file: file:///data/user/0/pl.trojmiasto.mobile/files/CodePush/c8e3ab71e0bf0290159abe04ce06ef1f8467aad5c07f5085fdc803cdd5afa67d/build/index.android.bundle
    

    Now it suggest JS bundle file doesn't exist or is broken but I gave up debugging it any more

  3. d-laskowski-trojmiasto commented on Aug 19, 2026

    @d-laskowski-trojmiasto
    Author

    Here is full log from update attempt with pure lib without any Cloude fixes:

    08-19 12:44:26.985 19288 19288 D CodePushDebug: Attempting to pre-initialize CodePush in onCreate...
    08-19 12:44:26.988 19288 19288 D CodePushDebug: CodePush.getInstance() called in onCreate()
    08-19 12:44:27.059 19288 19288 D ReactNative: [CodePush] Loading JS bundle from "assets://index.android.bundle"
    08-19 12:44:27.566 19288 19367 I ReactNativeJS: [CodePush] Checking for update.
    08-19 12:44:28.978 19288 19367 I ReactNativeJS: [CodePush] Downloading package.
    08-19 12:44:30.513 19288 19401 D ReactNative: [CodePush] Applying full update.
    08-19 12:44:30.527 19288 19367 I ReactNativeJS: [CodePush] Installing update.
    08-19 12:44:30.555 19288 19368 D ReactNative: [CodePush] Loading JS bundle from "/data/user/0/pl.trojmiasto.mobile/files/CodePush/6197e380feecf55b360c12cffa19040cfcc6a83939df2703bc1860f724c8eafb/build/index.android.bundle"
    08-19 12:44:30.555 19288 19368 D ReactNative: [CodePush] [MyDebug] Latest JS bundle for New Arch: /data/user/0/pl.trojmiasto.mobile/files/CodePush/6197e380feecf55b360c12cffa19040cfcc6a83939df2703bc1860f724c8eafb/build/index.android.bundle
    08-19 12:44:30.567 19288 19368 D ReactNative: [CodePush] Restarting app
    08-19 12:44:31.654 19288 19649 E ReactNativeJS: { [Error: Exception in HostFunction: java.net.MalformedURLException: no protocol: /data/user/0/pl.trojmiasto.mobile/files/CodePush/6197e380feecf55b360c12cffa19040cfcc6a83939df2703bc1860f724c8eafb/build/index.android.bundle]
    08-19 12:44:31.654 19288 19649 E ReactNativeJS:      message: 'java.net.MalformedURLException: no protocol: /data/user/0/pl.trojmiasto.mobile/files/CodePush/6197e380feecf55b360c12cffa19040cfcc6a83939df2703bc1860f724c8eafb/build/index.android.bundle',
    08-19 12:44:31.680 19288 19650 W unknown:BridgelessReact: ReactHost{0}.handleHostException(message = "Error: Exception in HostFunction: java.net.MalformedURLException: no protocol: /data/user/0/pl.trojmiasto.mobile/files/CodePush/6197e380feecf55b360c12cffa19040cfcc6a83939df2703bc1860f724c8eafb/build/index.android.bundle, stack:
    08-19 12:44:31.680 19288 19650 E AndroidRuntime: com.facebook.react.common.JavascriptException: Error: Exception in HostFunction: java.net.MalformedURLException: no protocol: /data/user/0/pl.trojmiasto.mobile/files/CodePush/6197e380feecf55b360c12cffa19040cfcc6a83939df2703bc1860f724c8eafb/build/index.android.bundle, stack:
    
  4. ofalvai commented on Aug 20, 2026

    @ofalvai
    Collaborator

    I spent some time trying to reproduce the crash, but ultimately couldn't.

    First, this log line:

    » android: codepush-plugin: SoLoader.init() not found in onCreate(). Placing CodePush initialization after super.onCreate().
    

    is a harmless warning, the expo plugin has a fallback logic that correctly patches your application subclass and you shouldn't worry about this. We should turn this warning into an info-level message, though.

    I don't want to rule out a bug in our Android code, but I couldn't reproduce the crash, no matter what Expo version or config change I tried. I think there is something unique to your project's setup, so a good next step would be to share as much as realistically possible: your Expo app config file, package.json, and if you are not using Expo CNG, then any Android-soide customization. And a broader logcat output would also be useful, I think there is a richer stacktrace that we are not seeing in the posted snippet.

  5. d-laskowski-trojmiasto commented on Aug 21, 2026

    @d-laskowski-trojmiasto
    Author

    app.config.ts:

    import { ExpoConfig, ConfigContext } from "expo/config";
    
    export default ({ config }: ConfigContext): ExpoConfig => ({
      ...config,
      name: "Trojmiasto.pl",
      slug: "app-trojmiasto-a",
      scheme: "trojmiasto-rn",
      version: "5.0.13",
      icon: "./assets/icon.png",
      userInterfaceStyle: "automatic",
      assetBundlePatterns: ["**/*"],
      ios: {
        icon: "./assets/liquid_glass.icon",
        supportsTablet: true,
        bundleIdentifier: "pl.trojmiasto.generalapp",
        googleServicesFile: "./GoogleService-Info.plist",
        entitlements: {
          "aps-environment": "production",
        },
        appStoreUrl: "https://apps.apple.com/pl/app/trojmiasto-pl/id522385310?l=pl",
        infoPlist: {
          LSApplicationQueriesSchemes: ["itms-apps", "itms-apps"],
          ITSAppUsesNonExemptEncryption: false,
          AppStoreID: "522385310",
          AppStoreCountry: "pl",
          UIDesignRequiresCompatibility: true,
          CFBundleLocalizations: ["pl"],
          CFBundleDevelopmentRegion: "pl",
          UIBackgroundModes: ["audio", "processing"],
        },
      },
      android: {
        adaptiveIcon: {
          foregroundImage: "./assets/adaptive-icon.png",
          backgroundImage: "./assets/adaptive-background.png",
          backgroundColor: "#0066cc",
        },
        package: "pl.trojmiasto.mobile",
        permissions: [
          "android.permission.RECORD_AUDIO",
          "android.permission.ACCESS_COARSE_LOCATION",
          "android.permission.ACCESS_FINE_LOCATION",
          "android.permission.FOREGROUND_SERVICE",
          "android.permission.WAKE_LOCK",
          "android.permission.IGNORE_BATTERY_OPTIMIZATION",
        ],
        googleServicesFile: "./google-services.json",
        playStoreUrl: "https://play.google.com/store/apps/details?id=pl.trojmiasto.mobile&hl=pl",
      },
      web: {
        favicon: "./assets/favicon.png",
      },
      plugins: [
        [
          "expo-build-properties",
          {
            ios: {
              useFrameworks: "static",
              buildReactNativeFromSource: true,
              forceStaticLinking: [
                "RNFBAnalytics",
                "RNFBApp",
                "RNFBCrashlytics",
                "RNFBFirestore",
                "RNFBMessaging",
              ],
            },
            android: {
              enableMinifyInReleaseBuilds: true,
              enableShrinkResourcesInReleaseBuilds: true,
            },
          },
        ],
        "expo-router",
        "expo-image-picker",
        "expo-dev-client",
        "react-native-compressor",
        "expo-location",
        [
          "expo-share-intent",
          {
            iosActivationRules: {
              NSExtensionActivationSupportsImageWithMaxCount: 12,
              NSExtensionActivationSupportsMovieWithMaxCount: 12,
            },
            androidIntentFilters: ["image/*", "video/*"],
            androidMultiIntentFilters: ["image/*", "video/*"],
          },
        ],
        [
          "react-native-android-widget",
          {
            widgets: [
              {
                name: "trojmiasto",
                label: "Trojmiasto.pl",
                minWidth: "250dp",
                minHeight: "110dp",
                targetCellWidth: 4,
                targetCellHeight: 2,
                resizeMode: "horizontal|vertical",
                description: "Trojmiasto.pl",
                previewImage: "./assets/widget-preview/trojmiasto.png",
                updatePeriodMillis: 1800000,
              },
            ],
          },
        ],
        "expo-font",
        [
          "expo-quick-actions",
          {
            androidIcons: {
              add_raport: "./assets/shortcuts/android/add_raport.png",
              service: "./assets/shortcuts/android/default.png",
            },
            iosIcons: {
              add_raport: "./assets/shortcuts/ios/add_raport.png",
              service: "./assets/shortcuts/ios/default.png",
            },
          },
        ],
        [
          "expo-notifications",
          {
            icon: "./assets/push.png",
          },
        ],
        [
          "@react-native-firebase/app",
          {
            ios: {
              disableSPM: true,
            },
          },
        ],
        [
          "@sentry/react-native/expo",
          {
            url: "https://sentry.trojmiasto.com/",
            project: "mobile-app",
            organization: "trojmiastopl",
          },
        ],
        "@react-native-firebase/app-check",
        [
          "expo-splash-screen",
          {
            backgroundColor: "#0066cc",
            image: "./assets/splash.png",
            imageWidth: 360,
          },
        ],
        "expo-video",
        "@react-native-firebase/crashlytics",
        "expo-background-task",
        "expo-audio",
        "./withBackgroundActions.js",
        "expo-asset",
        "react-native-quick-crypto",
        "@sentry/react-native",
        "@react-native-vector-icons/material-icons",
        [
          "@bitrise/code-push-sdk/expo",
          {
            ios: {
              CodePushDeploymentKey: process.env.BITRISE_KEY,
              CodePushServerURL: "https://5a01f9464038f235.codepush.bitrise.io",
            },
            android: {
              CodePushDeploymentKey: process.env.BITRISE_KEY,
              CodePushServerURL: "https://5a01f9464038f235.codepush.bitrise.io",
            },
          },
        ],
      ],
      extra: {
        router: {
          origin: false,
        },
        eas: {
          projectId: "d686c0a6-55ff-492e-b562-d61fcdb1f896",
          build: {
            experimental: {
              ios: {
                appExtensions: [],
              },
            },
          },
        },
      },
      owner: "trojmiasto_pl",
      runtimeVersion: {
        policy: "appVersion",
      },
      experiments: {
        reactCompiler: true,
      },
    });

    package.json:

    {
      "name": "trojmiasto-rn",
      "version": "1.0.0",
      "main": "index.ts",
      "scripts": {
        "start": "expo start --dev-client --tunnel",
        "prod": "npx expo start --no-dev --minify --tunnel",
        "android": "expo run:android",
        "ios": "expo run:ios",
        "web": "expo start --web",
        "lint": "eslint .",
        "fix": "eslint --fix .",
        "prepare": "husky",
        "postinstall": "patch-package",
        "e2e": "eas workflow:run .eas/workflows/e2e.yml",
        "ota-a": "npx expo export:embed --entry-file index.js --platform android --dev false --reset-cache --bundle-output ./build/index.android.bundle --assets-dest ./build --minify false && zip -r update-android.zip ./build && rm -rf ./build",
        "ota-i": "npx expo export:embed --entry-file  index.js --platform ios --dev false --reset-cache --bundle-output ./build/main.jsbundle --assets-dest ./build --minify false && zip -r update-ios.zip ./build && rm -rf ./build"
      },
      "dependencies": {
        "@bitrise/code-push-sdk": "^10.5.2",
        "@expo/react-native-action-sheet": "^4.1.1",
        "@expo/ui": "~57.0.10",
        "@lodev09/react-native-exify": "^1.0.3",
        "@react-native-async-storage/async-storage": "2.2.0",
        "@react-native-community/hooks": "^100.1.0",
        "@react-native-community/netinfo": "12.0.1",
        "@react-native-firebase/analytics": "^26.2.0",
        "@react-native-firebase/app": "^26.2.0",
        "@react-native-firebase/app-check": "^26.2.0",
        "@react-native-firebase/crashlytics": "^26.2.0",
        "@react-native-firebase/firestore": "^26.2.0",
        "@react-native-firebase/messaging": "^26.2.0",
        "@react-native-vector-icons/material-icons": "^13.1.2",
        "@sentry/react-native": "~7.11.0",
        "@shopify/flash-list": "2.0.2",
        "@tanstack/react-query": "^5.101.4",
        "@uppy/aws-s3": "^5.1.0",
        "@uppy/core": "^5.2.0",
        "@uppy/locales": "^5.1.1",
        "@uppy/tus": "^5.1.1",
        "axios": "^1.19.0",
        "events": "^3.3.0",
        "expo": "~57.0.12",
        "expo-asset": "~57.0.10",
        "expo-audio": "~57.0.3",
        "expo-background-task": "~57.0.9",
        "expo-build-properties": "~57.0.10",
        "expo-constants": "~57.0.10",
        "expo-dev-client": "~57.0.11",
        "expo-device": "~57.0.1",
        "expo-document-picker": "~57.0.1",
        "expo-font": "~57.0.1",
        "expo-image": "~57.0.2",
        "expo-image-manipulator": "~57.0.9",
        "expo-image-picker": "~57.0.9",
        "expo-in-app-updates": "^0.12.0",
        "expo-keep-awake": "~57.0.1",
        "expo-linear-gradient": "~57.0.1",
        "expo-linking": "~57.0.5",
        "expo-location": "~57.0.9",
        "expo-media-library": "~57.0.3",
        "expo-notifications": "~57.0.10",
        "expo-quick-actions": "^6.0.2",
        "expo-router": "~57.0.12",
        "expo-share-intent": "^8.0.1",
        "expo-splash-screen": "~57.0.6",
        "expo-status-bar": "~57.0.1",
        "expo-store-review": "~57.0.1",
        "expo-system-ui": "~57.0.2",
        "expo-task-manager": "~57.0.9",
        "expo-video": "~57.0.2",
        "expo-video-metadata": "^1.5.0",
        "expo-web-browser": "~57.0.2",
        "lodash": "^4.18.1",
        "patch-package": "^8.0.1",
        "react": "19.2.3",
        "react-dom": "19.2.3",
        "react-hook-form": "^7.85.0",
        "react-native": "0.86.2",
        "react-native-android-widget": "^0.22.0",
        "react-native-background-actions": "^4.1.0",
        "react-native-boost": "^1.6.0",
        "react-native-bouncy-checkbox": "^4.1.4",
        "react-native-compressor": "^2.0.3",
        "react-native-device-info": "^15.0.2",
        "react-native-gesture-handler": "~2.32.0",
        "react-native-keyboard-controller": "1.21.9",
        "react-native-mmkv": "^4.3.2",
        "react-native-nitro-modules": "^0.36.5",
        "react-native-notify-kit": "^10.5.0",
        "react-native-pager-view": "8.0.2",
        "react-native-progress": "^5.0.1",
        "react-native-quick-crypto": "^1.1.6",
        "react-native-reanimated": "4.5.1",
        "react-native-safe-area-context": "~5.7.0",
        "react-native-screens": "~4.26.0",
        "react-native-sortables": "^1.10.0",
        "react-native-spotlight-tour": "^4.0.0",
        "react-native-svg": "15.15.4",
        "react-native-tab-view": "^4.3.2",
        "react-native-toast-message": "^2.4.0",
        "react-native-walkthrough-tooltip": "^1.6.0",
        "react-native-webview": "13.16.1",
        "react-native-worklets": "0.10.1",
        "uuid": "^14.0.1",
        "zustand": "^5.0.14"
      },
      "devDependencies": {
        "@babel/core": "^7.29.7",
        "@eslint/compat": "^2.1.0",
        "@eslint/eslintrc": "^3.3.6",
        "@eslint/js": "^9.39.5",
        "@types/lodash": "^4.17.25",
        "@types/react": "~19.2.18",
        "@typescript-eslint/eslint-plugin": "^8.67.0",
        "@typescript-eslint/parser": "^8.67.0",
        "babel-plugin-module-resolver": "^5.0.3",
        "eslint": "^9.39.5",
        "eslint-config-expo": "~57.0.1",
        "eslint-config-prettier": "^10.1.8",
        "eslint-import-resolver-babel-module": "^5.3.2",
        "eslint-import-resolver-typescript": "^4.4.5",
        "eslint-plugin-import": "^2.32.0",
        "eslint-plugin-module-resolver": "^1.5.0",
        "eslint-plugin-prettier": "^5.5.6",
        "eslint-plugin-react-compiler": "^19.1.0-rc.2",
        "expo-mcp": "^0.2.4",
        "husky": "^9.1.7",
        "lint-staged": "^17.3.0",
        "prettier": "^3.9.6",
        "typescript": "~6.0.3"
      },
      "private": true,
      "lint-staged": {
        "*.{ts,tsx}": "eslint --fix --max-warnings 0"
      },
      "expo": {
        "doctor": {
          "reactNativeDirectoryCheck": {
            "exclude": [
              "@uppy/core",
              "@uppy/locales",
              "@uppy/tus",
              "lodash",
              "patch-package",
              "react-native-bouncy-checkbox",
              "react-native-spotlight-tour",
              "react-native-background-actions",
              "react-native-compressor",
              "@react-native-vector-icons/material-icons"
            ]
          }
        }
      },
      "overrides": {
        "zod-validation-error": "^4.0.0"
      },
      "allowScripts": {
        "@firebase/util@1.15.2": true,
        "@sentry/cli@2.58.4": true,
        "protobufjs@7.6.5": true,
        "unrs-resolver@1.11.1": true
      }
    }
    

    Not sure if this is helpful but here is my MainApplication.kt but I use CNG so it's generated by prebuild:

    package pl.trojmiasto.mobile
    
    import android.app.Application
    import android.content.res.Configuration
    
    import com.facebook.react.PackageList
    import com.facebook.react.ReactApplication
    import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
    import com.facebook.react.ReactPackage
    import com.facebook.react.ReactHost
    import com.facebook.react.common.ReleaseLevel
    import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint
    
    import expo.modules.ApplicationLifecycleDispatcher
    import expo.modules.ExpoReactHostFactory
    import com.microsoft.codepush.react.CodePush
    import pl.trojmiasto.mobile.R
    import android.util.Log
    
    class MainApplication : Application(), ReactApplication {
    
      override val reactHost: ReactHost by lazy {
        ExpoReactHostFactory.getDefaultReactHost(
          context = applicationContext,
          packageList =
            PackageList(this).packages.apply {
              // Packages that cannot be autolinked yet can be added manually here, for example:
              // add(MyReactNativePackage())
            },
          jsBundleFilePath = CodePush.getJSBundleFile()
        )
      }
    
      override fun onCreate() {
        super.onCreate()
        // CodePush: Initialize instance on app startup.
        try {
            Log.d("CodePushDebug", "Attempting to pre-initialize CodePush in onCreate...");
            val deploymentKey = getString(R.string.CodePushDeploymentKey);
            val isDebugMode = BuildConfig.DEBUG; 
            CodePush.getInstance(deploymentKey, this, isDebugMode);
            Log.d("CodePushDebug", "CodePush.getInstance() called in onCreate()");
        } catch (e: Exception) {
            Log.e("CodePushDebug", "Error pre-initializing CodePush in onCreate: " + e.message, e);
        }
    
        DefaultNewArchitectureEntryPoint.releaseLevel = try {
          ReleaseLevel.valueOf(BuildConfig.REACT_NATIVE_RELEASE_LEVEL.uppercase())
        } catch (e: IllegalArgumentException) {
          ReleaseLevel.STABLE
        }
        loadReactNative(this)
        ApplicationLifecycleDispatcher.onApplicationCreate(this)
      }
    
      override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig)
      }
    }

    Logs are filtered for codepush, without filter it's just unreadable constant stream (dozens of lines per second)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions