# The 10 Most Common Expo Errors and How to Fix Them

Most Expo errors fall into one of four layers: **Metro** couldn't bundle your code, **JavaScript** crashed at runtime, a **native module** is missing from the binary you're running, or the **native build** (Xcode or Gradle) failed. Naming the layer first is half the fix.

Here are the ten errors that come up most, what they mean and how to fix them. If yours isn't here, paste it into the free [React Native & Expo Error Fixer](https://www.rapidnative.com/tools/react-native-error-fixer?utm_source=hashnode&utm_medium=blog&utm_campaign=expo-common-errors) and it will explain the cause and the fix.

Before anything else, two commands fix a surprising number of problems:

```bash
npx expo start --clear     # restart Metro with an empty cache
npx expo-doctor            # check your project for known issues
```

## 1. Unable to resolve module

```
Unable to resolve module ./components/Header from App.tsx:
./components/Header could not be found within the project
```

**Layer:** Metro.

**Why:** the import path doesn't match a real file, the package isn't installed, or Metro is serving a stale cache after you moved or renamed something. A common one: the file is `header.tsx` but you import `./Header`. macOS ignores case, but Linux CI and EAS Build don't.

**Fix:**
- Check the path and the exact capitalisation.
- For a package, install it with `npx expo install <package>` so you get the version that matches your SDK.
- Restart with `npx expo start --clear`.
- If you use path aliases like `@/components`, make sure they're set in `tsconfig.json` (Expo reads `paths` from it).

[Paste your resolve error into the Error Fixer →](https://www.rapidnative.com/tools/react-native-error-fixer?utm_source=hashnode&utm_medium=blog&utm_campaign=expo-common-errors)

## 2. "main" has not been registered

```
Invariant Violation: "main" has not been registered.
```

**Layer:** JavaScript, at startup.

**Why:** the app's entry file never ran `registerRootComponent`, usually because something crashed while the first modules were loading, or Metro is running from the wrong folder (common in monorepos).

**Fix:**
- Scroll up: the real error is usually printed just above this one. Fix that first.
- Run `npx expo start` from the app's own folder.
- If you changed the entry point, check the `main` field in `package.json` (`expo-router/entry` for Expo Router, or a file that calls `registerRootComponent(App)`).

## 3. Text strings must be rendered within a `<Text>` component

```
Error: Text strings must be rendered within a <Text> component.
```

**Layer:** JavaScript, at render.

**Why:** a raw string or number is sitting directly inside a `View`. The sneaky version is a conditional: `{count && <Badge />}` renders the number `0` when `count` is 0.

**Fix:**
- Wrap text in `<Text>`.
- Make conditionals return a boolean: `{count > 0 && <Badge />}` or `{!!count && <Badge />}`.
- Look for stray characters, like a space or `;` left between JSX tags.

## 4. VirtualizedLists should never be nested inside plain ScrollViews

```
VirtualizedLists should never be nested inside plain ScrollViews
with the same orientation because it can break windowing and other functionality
```

**Layer:** JavaScript (a warning, but a real performance problem).

**Why:** a `FlatList` inside a vertical `ScrollView` renders every row at once, so you lose the virtualization that makes lists fast.

**Fix:** remove the outer `ScrollView` and move the content above and below the list into `ListHeaderComponent` and `ListFooterComponent`. If you need several lists on one screen, use a `SectionList`.

## 5. Native module not found in Expo Go

```
Error: Cannot find native module 'ExpoSomething'
Invariant Violation: TurboModuleRegistry.getEnforcing(...): 'RNSomething' could not be found.
```

**Layer:** native module.

**Why:** Expo Go only contains the native code for the libraries bundled into it. A library with its own native code that isn't one of them will install fine and then crash at runtime.

**Fix:** create a [development build](https://docs.expo.dev/develop/development-builds/introduction/), which is your own version of Expo Go with your libraries compiled in:

```bash
npx expo install expo-dev-client
eas build --profile development --platform ios   # or android
```

If you're already on a development build and see this, you added the library after building. Rebuild.

## 6. Element type is invalid

```
Element type is invalid: expected a string (for built-in components)
or a class/function (for composite components) but got: undefined.
```

**Layer:** JavaScript.

**Why:** an import resolved to `undefined`. Almost always a default/named import mix-up: `import Header from './Header'` when the file does `export function Header`, or the other way around. Circular imports can cause it too.

**Fix:** match the import to the export (`import { Header } from './Header'` for a named export). The error's component stack tells you which component was undefined.

## 7. Too many re-renders

```
Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
```

**Layer:** JavaScript.

**Why:** state is set during render. The classic: `onPress={setOpen(true)}` calls the function immediately instead of passing it.

**Fix:**
- Pass a function: `onPress={() => setOpen(true)}`.
- Move state updates that depend on props into an event handler or a `useEffect` with the right dependencies.
- The related "Maximum update depth exceeded" usually means a `useEffect` updates a value that's in its own dependency list.

## 8. Network request failed

```
TypeError: Network request failed
```

**Layer:** JavaScript, but the cause is usually the network setup.

**Why:** on a phone, `localhost` is the phone, not your computer. Other causes: plain `http://` URLs, which Android blocks by default (and iOS App Transport Security restricts), or a server that isn't reachable from the device's network.

**Fix:**
- Use your computer's LAN IP (for example `http://192.168.1.20:3000`) or a tunnel, and keep the phone on the same Wi-Fi.
- Use `https` for anything outside local development.
- Read the URL from an environment variable (`EXPO_PUBLIC_API_URL`) so dev and production can differ.

## 9. Package versions don't match your Expo SDK

```
The following packages should be updated for best compatibility with the installed expo version:
  react-native-reanimated@3.x.x - expected version: ~3.y.y
```

**Layer:** everywhere. Mismatched versions cause crashes at runtime and failures at build time.

**Why:** a library was installed with `npm install` instead of `npx expo install`, or the SDK was upgraded without updating its packages.

**Fix:**

```bash
npx expo install --fix
npx expo-doctor
```

When upgrading the SDK, follow the release notes and run `npx expo install expo@^<version> --fix`.

## 10. EAS Build failed

```
Gradle build failed with unknown error. See logs for the "Run gradlew" phase for more information.
```

or on iOS, a failed "Install pods" or "Run fastlane" phase.

**Layer:** native build.

**Why:** the last line rarely says much. The real cause is further up in the phase that failed: often a version mismatch (see #9), a config plugin that needs a setting you haven't added, or credentials and signing.

**Fix:**
- Open the failed phase in the EAS build page and search for the first `error:` line.
- Run `npx expo-doctor` and fix what it reports.
- Reproduce locally with `npx expo prebuild --clean` and then `npx expo run:android` or `npx expo run:ios`, which is much faster to iterate on than cloud builds.

[Paste the failed build log into the Error Fixer →](https://www.rapidnative.com/tools/react-native-error-fixer?utm_source=hashnode&utm_medium=blog&utm_campaign=expo-common-errors)

## A debugging routine that works for most of these

1. **Read the first error, not the last line.** Red screens and build logs often end with something generic.
2. **Name the layer:** Metro, JavaScript, native module or native build.
3. **Check how you run the app.** Expo Go, a development build and a bare project behave differently.
4. **Clear caches** with `npx expo start --clear` before deeper changes.
5. **Align versions** with `npx expo install --fix`.

If you're stuck on an error that isn't in this list, the free [React Native & Expo Error Fixer](https://www.rapidnative.com/tools/react-native-error-fixer?utm_source=hashnode&utm_medium=blog&utm_campaign=expo-common-errors) explains it in plain English: paste the error, choose where it happens and how you run the app, and it gives you the likely causes and the fix. It's made by RapidNative, where I work.

What's the Expo error that has cost you the most time? Drop it in the comments.

