Troubleshooting
Fixes for the most common failures - setup, bun and Node, Expo Go vs dev builds, env keys on EAS, sign-in redirects, paywalls, push and Metro.
Something broke? Here are the failures I see most, each with its fix. Start with
bun run doctor (Starter and Pro): it checks the versions, your keys, the config placeholders
and the EAS link in one go, and names what to fix.
setup prints "Already applied"
Symptom: bun run setup --ui tamagui (or any other flag) prints
Already applied - setup is one-way and removed itself and nothing changes.
Your tree is finalized: the first setup run deleted modules/ and left this one-line stub in
its place, so there's nothing to apply a new selection from. .readynative.json records what
you picked. To switch an option, start from a fresh clone of your tier repo -
Can I change a module after setup? has the steps.
Next time, bun run setup --keep-modules keeps the tree switchable.
Wrong bun or Node version
Symptom: bun install or a script fails early, doctor shows a red bun >= or node >=
line, or a script dies with an error about the .ts file extension.
scripts/*.ts run under plain node, which strips TypeScript natively only from 22.18 on, and
app.config.ts imports readynative.config.ts the same way. Update both:
bun upgrade
node --versionInstall Node 22.18 or newer (24 LTS is what I run) with your version manager of choice, then
run bun run doctor again. With npm, pnpm or yarn instead of bun, see
Package managers.
A native module is missing in Expo Go
Symptom: the app crashes on launch in Expo Go with something like
TurboModuleRegistry.getEnforcing(...): 'X' could not be found or "Cannot find native
module", usually right after picking MMKV, Unistyles, RevenueCat, Adapty or push.
Expo Go contains only its own bundled native modules. Those options ship native code, so they need a dev build: your own build of the app that works like Expo Go afterwards.
bunx expo run:ios
bunx expo run:androidOr build it in the cloud and install from the link:
bunx eas-cli build --profile development --platform iosThen start Metro with bun run start:dev and open the (Dev) app, not Expo Go. Rebuild whenever
you add a library with native code or change native config (readynative.config.ts ids,
icons, plugins). bun run setup prints whether your selection runs in Expo Go;
Expo Go or a dev build lists every module that doesn't.
A key is missing or ignored
Symptom: a screen says "Configure Supabase" (or the matching service), doctor reports
missing in .env, or you added a key and nothing changed.
-
Put keys in
.envat the repo root..env.examplelists every key your selection needs, each with a link to the dashboard that issues it. -
EXPO_PUBLIC_*values are inlined into the bundle when Metro builds it, so restart with a clear cache after editing.env:bun run start -- -c -
Read them as
process.env.EXPO_PUBLIC_Xwritten out in full. Expo inlines only static references;process.env[name]staysundefined. -
Works locally but not in an EAS build? See the next section.
-
Server keys (
STRIPE_SECRET_KEYand friends) never get theEXPO_PUBLIC_prefix. The app can't read them; onlysrc/app/api/**andsrc/server/**can.
A key works locally but not in an EAS build
Symptom: the app works with bun run start, but a build from EAS (TestFlight, Play internal
testing, a preview build) shows "Configure Supabase" or its service's equivalent, or an update
from eas update loses a key.
.env is gitignored, so EAS never uploads it. Set each key in the EAS environment the build
uses, with plaintext for EXPO_PUBLIC_* keys and sensitive for server keys:
bunx eas-cli env:set --environment production --name EXPO_PUBLIC_SUPABASE_URL --value https://xyz.supabase.co --visibility plaintextThen rebuild, or republish the update with --environment.
Environment variables → On EAS says which profile reads
which environment.
Supabase sign-in never comes back in Expo Go
Symptom: Google sign-in or a password-reset link opens the browser, you finish there, and the app never receives the session - you land on a Supabase error page or the site URL instead.
Supabase redirects only to URLs on its allow list. In a dev build the app's links start with
your scheme (readynative://), but in Expo Go they start with exp://<lan-ip>:8081/--/. In
Supabase, open Authentication → URL Configuration → Redirect URLs and add exp://** to your
development project (never production), next to your scheme's entries. The
Supabase page lists them all.
RevenueCat shows no offerings or no prices
Symptom: the paywall is empty, offerings.current is null, or packages load without a
price.
RevenueCat can show only what the store hands it. Work down this list:
- Paid Apps Agreement: App Store Connect → Business must show the Paid Apps Agreement as active, with banking and tax forms complete. Until then StoreKit returns no products at all.
- Product status: each subscription in App Store Connect needs its metadata filled in so it reaches "Ready to Submit" (a price, a localized name, a review screenshot). On Play, the product must be active.
- Offering: in RevenueCat, the products are attached to a package in an offering marked current.
- Tester: purchases and prices come through on a real device signed into a sandbox Apple ID
(or a Play license tester). A RevenueCat Test Store key (
test_…) skips all of this in development.
The RevenueCat page walks the dashboards.
The push token is null
Symptom: push.usePushToken() stays at token: null with status unsupported, and the dev
console warns "remote push needs a physical device".
Simulators and emulators never get a remote push token, and Expo Go doesn't receive remote push
since SDK 53. Install a dev build on a physical phone (bunx eas-cli build --profile development,
or bunx expo run:ios --device) and open that. If the status is unsupported on a real phone,
app.easProjectId in readynative.config.ts is empty - run bunx eas-cli init and paste the id.
Local notifications work everywhere except the web. See
Add push notifications and the Push
module page.
EAS build or credentials fail
Symptom: eas build stops before the build starts, or the build fails at signing.
- Not logged in / wrong account:
bunx eas-cli whoami, thenbunx eas-cli login. - No project id:
eas initcan't write intoapp.config.ts; it only prints the id. Paste it intoapp.easProjectIdinreadynative.config.ts(or setEAS_PROJECT_IDin CI). - The project belongs to an organisation: set
app.ownerto the organisation slug, or CI builds with an orgEXPO_TOKENare rejected. - iOS signing: run the first iOS build interactively so EAS can sign in to your Apple
Developer account and create the certificate and provisioning profile. A paid Apple
Developer membership is required; a free Apple ID can't build for the store. "Bundle
identifier is not available" means someone already registered that id - change
app.ios.bundleId. - Inspect or reset stored credentials:
bunx eas-cli credentialsshows the iOS certificates, the Android keystore and the service account keys for each platform. Don't delete an Android keystore that has already uploaded to Play - you'd lose the upload key. --non-interactivein CI fails on credentials: run one build interactively first so the credentials exist on EAS.
git apply says "does not exist in index"
Symptom: piping a diff between two release tags into git apply stops with
error: <path>: does not exist in index and applies nothing.
git apply is all-or-nothing, and the upstream diff touches paths your finalized tree doesn't
have: module files live under modules/<category>/<option>/files/ upstream but at the root in
your tree, the UI kit moved to src/components/ui, and setup removed the demo screens and its
own scripts. Map the paths, and let git merge around your edits:
- For a module, add
--relative=modules/<category>/<option>/filestogit diff. - For the UI kit, add
--relative=modules/ui/<your-stack>/files/src/ui/<your-stack>togit diffand--directory=src/components/uitogit apply. - Always pass
--3waytogit apply, and add--exclude=<path>for every path the error still names.
Update from upstream has the full commands.
Metro serves stale code
Symptom: a change doesn't show up, an import you deleted still errors, or the app shows
"Unable to resolve module" for a file that exists - typically after bun run setup, switching
branches or editing babel.config.js / metro.config.js.
bun run start -- -cIf that doesn't do it, reinstall and clear Expo's local cache:
rm -rf node_modules .expo
bun install
bun run start -- -cFor a dev build that still misbehaves after native changes, rebuild it: bunx expo run:ios
(or run:android) regenerates the native projects from config.
Still stuck?
bunx expo-doctor checks dependency versions against your Expo SDK, and
bunx expo install --fix aligns them. If that's clean too, send the command, the full error
and your bun run doctor output through the support form.