Extreme Aggravation with Builds servers caching code


This is a continuation of the issue under here: Extreme Aggravation with OTA Updates

I disabled OTA updates as Brent Vatne suggested, but some new users are still initially getting the extremely old code from several months ago. This ruins the app for them and makes it unusable.

It is also severely straining my relationship with my client. So right now I’m stuck between a sword and a hard place because the only way out i see is ejecting, but push notifications are known to not work well once you eject, and it could take me a couple of days to get that working.

I’m incurring financial losses due to un-budgeted time spent on these expo build difficulties and I would appreciate any guidance.

I was re-reading the “How Expo Works” page and I saw this: “If you build a standalone app with Expo, that standalone binary will also ship with a “pre-cached” version of your JavaScript so that it can cold launch the very first time with no internet.”

Is there a way to control which version is cached in my bundle? It seems to want to cache something from like 4 months ago.

I realized even ejecting won’t really help. If I can’t figure out a solid way around this situation I will have to start a new project from scratch and copy-paste all the code, then reimplement push notifications. (Both client and server side, which will be a big loss of time and income to me).

Can someone help me look into what’s going wrong with my build on the expo servers? My current JS code is not getting included in my bundle.

The build server uses the currently published bundle to build the app (at least last time I had this issue). I once had a similar issue because I had only made changes to the app.json file, and didn’t need it published. So I was doing builds using the --no-publish flag. This basically meant I was building the same IPA/APK over and over again with the old code.

Another thing to check is if your current binary using the same release channel that your publishing too? Otherwise you aren’t updating the live app, you’re updating a different channel all together.

Also, if you currently approved binary was build on a different SDK than you are publishing with, it will not update. You’ll need to make and submit a new binary using the new SDK, and you should be good.

There’s also a timeout interval that you can set in app.json.

  "expo": {
    "updates": {
      "fallbackToCacheTimeout": 15000

It’s in milliseconds (15 seconds above). If that is set to 0, then no matter what on first launch it will launch with the code the binary was built with. Only on the next launch (from terminated) will it update.

Last resort, there’s an Updates SDK you can look at:

Something like:

const update = await Expo.Updates.checkForUpdateAsync();
if (update.isAvailable) {
  // do stuff, see: await Expo.Updates.fetchUpdateAsync();

And last last resort (which I know isn’t always easy) is just make sure you’re on the latest SDK.

Best of luck. Let me know how it goes.


Thanks for writing up that thorough answer @theorytank. !

@vic616283 – I’m sorry you had trouble with this. There is a fair amount of inherent complexity here and, in general, we try to give you the flexibility to implement the policy that works best for you, but when there are lot of variables, things can definitely be confusing. If you have any concrete ideas about what would make this simpler for you, please let us know.

Thanks for trying to help @ccheever and @theorytank. My issue remains far from resolved though.

Here are some additional information bits:

  1. The JS bundle that is being included in my stand alone apps is from about November.
  2. I have published my build like 7 times (basically button mashing it) since November by runninng expo publish but also by clicking the publish button in the expo browser app (what gets launched when you start the app, I forget the official name)
  3. The release channels option is super useful, but I’m building everything through the default channel and managing this on testflight/google play
  4. I have disabled OTA updates already, and I have been building and submitting binaries in order to attempt to update the application. The core problem I have is that the binaries are built with a months-old JS bundle.
  5. Upon further testing what is actually happening is the standalone app gets built (apparently) with this super old bundle, the user opens it and the app is unusable, but if they close the app and reopen it, then it does have the new bundle.
  6. Based on the speed with which the app opens upon this second launch I am not even sure that it’s actually needing to download the new bundle.
  7. Although there is indeed quite a bit of complexity in this process and I confess i don’t understand the app store process as well as many others, and that therefore it is certainly possible that I am making some silly mistake, I would appreciate if we investigate the situation without necessarily assuming that everything is working perfectly on the expo side and I’m messing something up.

I have considered using the updates sdk but that can be super slow and leave the user with the feeling that the app is frozen at the splash screen. This is unacceptable to me and my stakeholders. I just need to get my current bundle building and included with my app.

Is it possible that the expo team could nuke all the old builds I’ve published to ensure that they won’t be the ones included with new binaries I create?

Another thing that occurs to me is that, if you folks could help me by telling me the url structure where my bundle is stored, I could have fastlane pilot check if the bundle inside the IPA has the same filename and size as the one that was last published to expo and at least give me an error if this isn’t the case. Then I can manually dig into the ipa and replace the old bundle with the new one before running fastlane pilot again.

I try really hard to not ask for help unless I’m at like my wit’s end. Whenever I have something I need help with, I try to help with the blocking and tackling of other posts asking for basic programming help or basic react native help. I appreciate what the team at expo does and I’d be immensely thankful if we could get this resolved.

1 Like

This is still not resolved. I have a super granular question then.

Is there anywhere in the xcode project (after it’s been bundled into an ipa) that points to my build by using the url i can see in my browser? (eg https://exp-shell-app-assets.s3.us-west-1.amazonaws.com/ios/%40vic616283/kiddiekredit-hash-archive.ipa)

If not, does the bundleUrl in xcode at least include the filename (eg “kiddiekredit-hash-archive.ipa” in the example above).?

Hey @vic616283,

Would it be possible for you to send us one of the affected IPAs so we can dig into this? You can email secure@expo.io or DM me @adamjnav on the Expo Developers Slack.



I’m trying to dig into this more myself but i don’t even know where the main.jsBundle file (or index.adroid.js) is supposed to be… Non-expo react native apps have these files but the expo generated builds i get don’t have it. Can anyone tell me where the js bundle is stored inside the ipa/apk?

Hi @vic616283 - the bundle file is stored at Payload/ExpoKitApp.app/shell-app.bundle in IPA files and in assets/shell-app.bundle in APK files (though you’ll need to use something like apktool to unzip them, I believe).

Nah they’re just zip files you can simply change the exception and poke in there, or android studio also has an apk analyzer tool in it.

Thanks a lot for your response homie. With that, i’m just gonna build a script to verify a hash of my bundle into my fastlane upload script.

Wow so guess what. I did a TON more trial and error and after many iterations i got to the point where I could identify that the error still happens if you update the app through testflight but if you uninstall and install new version, everything is fine. So this was actually some obscure ass thing in testflight with maybe the apple store caching files or something. Awful, just awful. Sorry for blaming it on expo.

1 Like

No worries, @vic616283! We’ve all hit that point of pure frustration and sometimes it helps to just let off some steam. We’re just glad you got things working. Hopefully things are smoother from here on out for ya!

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.