IOS - Bundle Assets Error When Building Release (403)

Hello, I have a newly created Bare Workflow application which when building in release mode for IOS throws the following error on bundling assets:

~/PROJECT/apps/native ~/PROJECT/apps/native/ios
3.18.6
[10:40:12] Request failed with status code 403
[10:40:12] Error: Request failed with status code 403
    at createError (/Users/mitch/.nvm/versions/node/v12.6.0/lib/node_modules/expo-cli/node_modules/axios/lib/core/createError.js:16:15)
    at settle (/Users/mitch/.nvm/versions/node/v12.6.0/lib/node_modules/expo-cli/node_modules/axios/lib/core/settle.js:17:12)
    at RedirectableRequest.handleResponse (/Users/mitch/.nvm/versions/node/v12.6.0/lib/node_modules/expo-cli/node_modules/axios/lib/adapters/http.js:211:9)
    at RedirectableRequest.emit (events.js:315:20)
    at RedirectableRequest._processResponse (/Users/mitch/.nvm/versions/node/v12.6.0/lib/node_modules/expo-cli/node_modules/axios/node_modules/follow-redirects/index.js:269:10)
    at ClientRequest.RedirectableRequest._onNativeResponse (/Users/mitch/.nvm/versions/node/v12.6.0/lib/node_modules/expo-cli/node_modules/axios/node_modules/follow-redirects/index.js:50:10)
    at Object.onceWrapper (events.js:422:26)
    at ClientRequest.emit (events.js:315:20)
    at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:610:27)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:116:17)
Command PhaseScriptExecution failed with a nonzero exit code

Observations / Things We’ve Checked

  1. We are using import { registerRootComponent } from 'expo';
  2. We’ve published the application with expo export and hosting the content on S3.
  3. The asset links are accessible there with no 403.
  4. Debug mode works fine.
  5. Removing the following fixes the build by not bundling assets however the assets are still present in the assets folder:
"assetBundlePatterns": [
      "**/*"
    ],

Weirdly on a colleagues machine this does not happen however when he opens the app it’s clear the assets have no been bundled.

Thanks in advance!

1 Like

I am very new to Expo as well so I might be wrong. But I was having the same problem and looks like if I sign in to expo and then do a build it works. However that’s not I wanted. Also noticed as you mentioned if we remove all the static assets it seems be working.

In addition, we are trying to wire up expo/packages/expo-updates at master · expo/expo · GitHub bundle to a large App and to isolate the problem we did following.

  1. Create a new RN application using Expo CLI and selected the bare template
  2. Ran the expo export command with public-url set to a public AWS S3 location
  3. Ran the ./gradlew clean assembleRelease from android folder.
  4. Build fails with following error.

> Task :app:bundleReleaseExpoUpdatesAssets FAILED

[20:04:42] Request failed with status code 403

[20:04:42] Set EXPO_DEBUG=true in your env to view the stack trace.

I thought that if we use an our own static hosting server then we don’t need to have an account with Expo. Maybe I am missing a step?

I enabled Charles proxy to see what’s going on. It seems like request get dispatched to https://d1wp6m56sqw74a.cloudfront.net/~assets/ca12bd32324a96a1e12f2754e1829c68 and returns 403. In my sample I have set the public-url as a GitHub URL so wonder what’s this URL is.

I found @notbrent ejected-example-fonts (GitHub - brentvatne/ejected-example-fonts) to be a good place to start. I can get this running in release mode with an image by using the icon.png he has included, however as soon as I add my own .png image to the assets folder and switch the require to that instead I get this error again.

Could this be a file type issue? :woman_shrugging:

Well I think release build hook check if the asset already in the cloud front and if the asset not exists in the cloud front then try to publish. So if you have not sign in to Expo there is no authenticated session and AWS rejects the publish request.
But I assume that if we use our own static hosting solution ( defined in public url ) expo hook should not be doing this process at all. Is there a config to turn off publish?

I followed the flow little bit deep. So in Android there is a hook to release build which fires up following command and that one seems try to publish the assets to AWS cloud front.

~/node_modules/expo-updates/expo-updates.gradle

commandLine("./node_modules/expo-updates/run-expo.sh", "bundle-assets", projectRoot, "--platform", "android", "--dest", assetsDir)

The same flow can be found for iOS builds as well,

~/node_modules/expo-updates/bundle-expo-assets.sh

expo bundle-assets --platform ios --dest "$dest"

Internally, the following command is getting executed:

expo bundle-assets <source-path> --platform <ios|android> --dest <destintion-path>

I went through the expo-cli code and I think the problem is here:

It gets called only if there are assets, hence the app builds if there are no assets.

I was able to test if that config can be overriden by changing this line locally:
https://github.com/expo/expo-cli/blob/master/packages/xdl/src/detach/Detach.js#L538
to

const context = {published : {url: "http://127.0.0.1:8000"}, config : manifest};
await AssetBundle().bundleAsync(context, manifest.bundledAssets, args.dest);

So just to test the theory, I rerouted all the Expo cloud-front traffic to a simple HTTP server hosting the dist assets using Charles proxy. So the build get successful!

Wonder this can be added as a feature for detached/bare workflow users they can specify the asset location so expo can start reading the assets from there.

thanks for the detective work everyone! looking into this now.

edit: here’s a pull request to fix it Get the public exported url set by expo export from the manifest and pass in to bundleAsync by brentvatne · Pull Request #1999 · expo/expo-cli · GitHub - i’ll land this hotfix once tests pass and deploy it soon

hey folks, give expo-cli@3.19.2 a spin, this should resolve your issue. really appreciate you all digging in and giving us useful information to help debug.

@samithaf - i also confirmed that you do not need sign in / have an expo account to use this expo export flow with expo-updates by doing my testing around the above fix in both signed in and signed out states

2 Likes

Thank you @notbrent for the fix and it was super quick. I just updated the CLI version and test the flow and it works fine.

1 Like

Thanks chaps, can confirm 3.19.2 is working for me too!

I’m having exactly the same issue using expo-cli 3.27.14
Currently set Charles up to redirect cloudfront back to localhost:9000/

I’m not entirely sure what’s causing it, it worked absolutely fine yesterday/last night, but gives me 403 on a new asset png I added to the project today - Still unclear why it’s even trying to reach out to Cloudfront when I’ve exported the assets to a local dist folder, and running a local asset server.