Expo Application Services
API Reference

Troubleshooting build errors and crashes

This document is under active development; the topic it covers is expansive and finding the right way to explain how to troubleshoot issues will take some trial and error. Your suggestions for improvements are welcome as pull requests.
When something goes wrong, it probably will go wrong in one of two ways: 1) your build will fail, or 2) the build will succeed but encounter a runtime error, eg: it crashes or hangs when you run it.
All standard advice around narrowing down the source of an error applies here; this document provides information that may be useful on top of your typical troubleshooting processes and techniques. Troubleshooting is an art, and you might need to think creatively.

Find the related error logs

Before you go further, you need to be sure that you have located the error message and read it. How you do this will be different depending on whether you're investigating a build failure or runtime error.

Refer to the debugging guide to learn how to locate logs when your release builds are crashing at runtime.

Go to your build details page (find it on the build dashboard if you don't have it open already) and expand any failed build phases by clicking on them. Often, the earliest phase with errors will contain the most useful information and any subsequent failed phase will have cascaded from the first.
Regardless of the phase, it's common to see log entries prefixed with [stderr], but keep in mind that this doesn't necessarily mean those logs point to errors; it's common for CLI tools to use stderr to output warnings and other diagnostics.
For example, you might see something like this on your Android builds:
[stderr] Note: /build/workingdir/build/app/node_modules/@react-native-async-storage/async-storage/android/src/main/java/com/reactnativecommunity/asyncstorage/ uses or overrides a deprecated API.[stderr] Note: Recompile with -Xlint:deprecation for details.
While you may or may not be interested in following up on that warning, it is not the cause of your failed build. So how do you know which logs are truly responsible? If you are building a bare project, you will already be good at this. If you are building a managed project, it may be tricky because you don't directly interact with the native code, only write JavaScript.
A good path forward is to determine if the build failed due to a native or JavaScript error. When your build fails due to a JavaScript build error, you will usually see something like this:
โŒ Metro encountered an error:Unable to resolve module ./src/Routes from /Users/expo/workingdir/build/App.js
This particular error means that the app is importing ./src/Routes and it is not found. The cause could be that the filename case being different in Git than the developer's filesystem (eg: routes.js in Git instead of Routes.js), or maybe the project has a build step and it wasn't set up to run on EAS Build. In this case, it turns out that in this case ./src/Routes was intended to import ./src/Routes/index.js, but that path was accidentally excluded in the developer's .gitignore.
It's important to note that with iOS builds the build details page only displays an abridged version of the logs, because the full output from xcodebuild can be in the order of 10MB. Sometimes it's necessary to open the full Xcode logs in order to find the information that you need; for example, if the JavaScript build failed but you don't see any useful information on the build details page. To open the full Xcode logs, scroll to the bottom of the build details page when the build has completed and either click to view or download them.
If you are working on a managed app and the build error is a native error rather than a JavaScript error, this is likely due to a config plugin or a dependency in your project. Keep an eye out in the logs for any new packages that you've added since your previous successful build. Run expo doctor to determine that the versions of Expo SDK dependencies in your project are compatible with your Expo SDK version.
Armed with your error logs, you can often start to fix your build, or you can search the forums and GitHub issues for related packages to dig deeper. Some common sources of problems are listed below.
๐Ÿ“ฆ Are you using a monorepo?
Monorepos are incredibly useful but they do introduce their own set of problems. A monorepo that you have set up to work with expo build will not necessarily work with eas build.
With EAS Build, it's necessary to upload the entire monorepo to the build worker, set it up, and run the build; but, on expo build you only had to be able to build the JavaScript bundle locally and upload that to the worker.
EAS Build is more like a typical CI service in that we need the source code, rather than a compiled JavaScript bundle and manifest. EAS Build has first-class support for Yarn workspaces, and your success may vary when using other monorepo tools.
๐Ÿ’ฅ Out-of-memory (OOM) errors
If your build fails with "Gradle build daemon disappeared unexpectedly (it may have been killed or may have crashed)" in your Gradle logs, this may be because the Node process responsible for bundling your app JavaScript was killed.
This can often be a sign that your app bundle is extremely large, which will make your overall app binary larger and lead to slow boot up times, especially on low-end Android devices. Sometimes the error can occur when large text files are treated as source code, for example if you have a JavaScript file that contains a string of 1MB+ of HTML to load into a webview, or a similarly sized JSON file.
To determine how large your bundle is and to see a breakdown of where the size comes from, use react-native-bundle-visualizer.
It's not yet possible to increase memory limits on your build workers, only one worker configuration is currently available.

When you get the Metro encountered an error during a native iOS build, it means Metro bundler failed to bundle the app. This unfortunately runs at the end of the native build process, meaning it takes a while to fail.
โŒ Metro encountered an error:
You can reproduce this production bundle locally by running expo export --experimental-bundle which simply creates a production bundle. Continue doing this until the command passes without throwing. In general this should save you hours of debugging time.
This behavior comes from React Native on iOS, in the future we plan to rewrite this for EAS Build so the bundle is created before the native runtime.

If the logs weren't enough to immediately help you understand and fix the root cause, it's time to try to reproduce the issue locally. If your project builds and runs locally in release mode then it will also build on EAS Build, provided that the following are all true:
  • Relevant Build tool versions (eg: Xcode, Node, npm, Yarn) are the same in both environments. Learn more.
  • Relevant environment variables are the same in both environments. Learn more.
  • The archive that is uploaded to EAS Build includes the same relevant source files. Learn more.
You can verify that your project builds on your local machine with the expo run commands with variant/configuration flags set to release to most faithfully reproduce what executes on EAS Build. (Learn more about the iOS build process and Android build process).
# Locally compile and run the Android app in release mode
โ†’ย expo run:android --variant release

# Locally compile and run the iOS app in release mode
โ†’ย expo run:ios --configuration Release
In managed projects, these commands will run expo prebuild to generate native projects โ€” you likely want to clean up the changes once you are done troubleshooting.
๐Ÿ’ก Don't have Xcode and Android Studio set up on your machine?
If you do not have native toolchains installed locally, for example because you do not have an Apple computer and therefore cannot build an iOS app on your machine, it can be trickier to get to the bottom of build errors. The feedback loop of making small changes locally and then seeing the result on EAS Build is slower than doing the same steps locally, because the EAS Build worker must set up its environment, download your project, and install dependencies before starting the build.
If you are willing and able to set up the appropriate native tools, then refer to the React Native environment setup guide.
If your native toolchains are installed correctly and you are unable to build and run your project in release mode on your local machine, it will not build on EAS Build. Fix the issues locally, then try again on EAS Build. The other advice in this doc may be useful to help you resolve the issue locally, but often this requires some knowledge of native tooling or judicious application of Google, StackOverflow, and GitHub Issues.

If you find yourself in this situation, it's time to narrow down what configuration exists on your machine that hasn't been set up for your project on EAS Build yet.
There are two ways to approach this, which are quite similar:
  • Do a fresh git clone of your project to a new directory and get it running. Pay attention to each of the steps that are needed and verify that they are also configured for EAS Build.
  • Run a local build with eas build --local. This command will locally run a process that is as close as it can be to the remote, hosted EAS Build service. Learn how to set this up and use it for debugging.

The classic build service (expo build) works completely differently from EAS Build, and there is no guarantee that your app will work out of the box on EAS Build if it works on the classic build service. You can learn more about migrating from expo build in the guide, and get a better understanding of how these two services are fundamentally different in this two-part blog post.

You can test how the JS part of your app will run in production by starting it with expo start --no-dev. This tells the bundler to minify JavaScript before serving it, most notably stripping code protected by the __DEV__ boolean. This will remove most of the logging, HMR, Fast Refresh functionality, and make debugging a bit harder, but you can iterate on the production bundle faster this way.

This guide is far from being comprehensive, and depending on your level of experience you might still be struggling to get your app working.
If you have followed the advice here, you're now in a good position to describe your issue to other developers and get some help.

Join us on Discord or the forums to ask for help from the community and the Expo team. The Expo team does our best to respond to high quality and well articulated questions and issues, but responses are not guaranteed unless you are signed up for a support plan.
When you ask for troubleshooting help, be sure to share the following information:
  • A link to your build page. This can only be accessed by your team or Expo employees. If you'd like to share it more publicly, take a screenshot. If you'd like to share it more privately, send an email to and mention that in your help request on chat or forums. If you are performing this build locally with eas build --local, you may omit this, but please indicate this fact.
  • Error logs. Anything that you suspect may be related to your build or runtime error. If you can't provide this, please explain why not.
  • Minimal reproducible example or a link to your repository. The quickest way to get a solution to your problem is to ensure that other developers can reproduce it. If you have ever worked on a team, you know this from experience. In many cases, if you can't provide a reproducible example then it may not be possible to help you, and at best the back-and-forth process of asking and answering questions will be an inefficient use of time. Learn more about how to create a reproducible example in the manual debugging guide and StackOverflow's "Minimal Viable Reproducible Example" guide.
Try to be clear, precise, and helpful. General guidance provided by StackOverflow's "How to ask a good question" guide applies.