Troubleshooting

Fix common setup, runtime, build, and release issues.

Most Expo template issues come from one of four places: Metro cache, public env values being inlined into the bundle, using Expo Go for a native-module feature, or mismatched variant identifiers.

Quick reset

Start with the checks the template already expects:

pnpm typecheck
pnpm lint
pnpm dev

pnpm dev runs expo start -c -p 3000, so it clears Metro cache and uses the documented development port.

For a deeper local reset:

watchman watch-del-all
rm -rf .expo
pnpm dev

Use pnpm clean only when you intentionally want to remove node_modules too.

Setup and Metro

SymptomLikely causeFix
Metro starts but the app shows stale copy/configEnv values are inlined and the old bundle is still runningStop Metro, restart with pnpm dev, then reload the app
Port 3000 is busyAnother dev server is runningStop the other process or run expo start -c -p <port> manually
iOS simulator does not appearXcode simulator runtime is missing or not installedOpen Xcode, install a simulator runtime, then rerun pnpm ios
Android emulator fails to bootAndroid Studio SDK or JAVA_HOME is not configuredOpen Android Studio, install SDK/platform tools, and verify the emulator outside Expo
File watcher behaves oddlyWatchman cache is staleRun watchman watch-del-all and restart Metro

Environment variables

SymptomLikely causeFix
Supabase client errors at startupMissing EXPO_PUBLIC_SUPABASE_URL or EXPO_PUBLIC_SUPABASE_ANON_KEYCopy .env.example to .env.local, set both values, and restart Metro
Provider remains disabled after setting a keyThe old JS bundle still has the previous envRestart Metro with cache clear; for EAS builds, create a new build
Secret appears in the app bundleA server secret was put in EXPO_PUBLIC_*Rotate the secret and move it to Supabase Edge secrets, EAS secrets, or CI secrets
Preview build uses production backendVariant-specific env was not set for the EAS profileCheck EAS env values and APP_VARIANT for the profile

EXPO_PUBLIC_* values are public. Do not put service-role keys, REVENUECAT_WEBHOOK_AUTH, APNs keys, or SENTRY_AUTH_TOKEN in them.

Expo Go vs development builds

SymptomLikely causeFix
Purchases say they are not configured or unavailablereact-native-purchases needs a native buildUse eas build --profile development --platform ios or Android equivalent
Google Sign-In button failsNative Google Sign-In module and OAuth clients require a native buildConfigure Google client IDs and test in a dev or store build
Native module cannot be foundExpo Go does not bundle that native dependencyInstall and open the template's development client
Push token is nullSimulator, web, denied permission, or no real device tokenTest on a physical device and request notification permission
Haptics, biometrics, or ATT no-opPlatform fallback or unsupported hardwareTest on supported iOS/Android hardware

Expo Go is still useful for early UI and web-compatible flows. Use development builds for purchases, Google Sign-In, realistic notifications, biometric lock, and store-review behavior.

Auth and redirects

SymptomLikely causeFix
Email verification opens a dead endRedirect URL is not allowed in Supabase Auth settingsAdd the active scheme callback for the current variant
OAuth returns to the wrong appBundle/scheme variant mismatchUse soar-starter-expo-dev, soar-starter-expo-preview, or soar-starter-expo consistently
Session disappears on nativeSecureStore write failed or stored session chunks are staleSign out/in, clear app data, and check lib/secure-store-chunked.ts if custom session data grew
Signed-out users can see public screensThis is intentionalProtect actions with SignInGate or require auth in the route you add

Google Sign-In

SymptomLikely causeFix
Google button says not configuredMissing EXPO_PUBLIC_GOOGLE_WEB_CLIENT_IDAdd the web client ID used by Supabase Google provider
Native Google flow fails on iOSMissing or wrong EXPO_PUBLIC_GOOGLE_IOS_CLIENT_IDCreate an iOS OAuth client for the bundle ID being tested
Android sign-in fails after release signingSHA-1 fingerprint mismatch in Google CloudAdd fingerprints for the debug, upload, or Play signing certificate you use
Supabase rejects the tokenGoogle provider is not configured in SupabaseEnable Google provider and use the same OAuth client setup

Supabase data and storage

SymptomLikely causeFix
Todos or uploads fail with RLS errorsMigrations were not appliedRun supabase db push against the linked project
TypeScript does not know a new tabletypes/database.ts is staleSet SUPABASE_PROJECT_ID and run pnpm gen:types
Upload sample says env is missingStorage helper reads the public Supabase pairSet EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY
Avatar upload fails but sample upload worksAvatar uses a separate bucket path from sample uploadsCreate or verify the avatar bucket and policies required by your profile flow

RevenueCat

SymptomLikely causeFix
Paywall shows no packagesNo current offering, products are not attached, or store metadata is incompleteFix the RevenueCat offering and wait for store sync
Purchases work in RevenueCat but app stays freeSupabase subscriptions row is missing or not entitledCheck webhook URL, REVENUECAT_WEBHOOK_AUTH, and function logs
Development build cannot load productsBundle/package ID does not match store product setupCreate products for the active variant or test the production ID
Android purchase does not unlock entitlementThe shipped webhook ignores PLAY_STOREExtend providerForStore() and the billing provider enum before relying on Android entitlements

Push notifications

SymptomLikely causeFix
Permission request works but no server push arrivesToken is not persisted by the templateAdd a device_tokens table and save the Expo push token
send-test-push failsThe optional function queries a table the template does not shipAdd the table and registration path, or replace it with Expo push API sending
Android notifications have odd behaviorNotification channel setup changed or permission was deniedRecheck lib/notifications.tsx and Android POST_NOTIFICATIONS permission
Web has no real push flowCurrent implementation is native-focusedAdd a separate web push implementation if your product needs it
SymptomLikely causeFix
Custom scheme link opens nothingWrong variant schemeUse soar-starter-expo-dev://, soar-starter-expo-preview://, or soar-starter-expo://
Universal/App Link does not open the appAASA or assetlinks file is missing or not verifiedHost the required files for EXPO_PUBLIC_LINKING_DOMAIN and rebuild native apps
URL opens the app but not the routeRoute is not in the allow-list resolverUpdate lib/deep-links.ts for your product routes
Notification tap goes nowhereNotification payload lacks a supported URLSend a URL that resolveDeepLinkHref() accepts

EAS and OTA

SymptomLikely causeFix
OTA update does not arriveChannel or runtime version mismatchPublish to the build's channel and app version
Native change is missing after OTAOTA cannot ship native modules, permissions, or config plugin changesCreate a new EAS build
Store build has wrong app name or bundle IDAPP_VARIANT was not productionCheck the production profile env and rebuild
Sentry sourcemaps are missingSENTRY_AUTH_TOKEN was not available during uploadStore it as an EAS or CI secret and run the sourcemap upload step
Version gate test never appearsEnv update config was not in the running bundleRestart Metro or rebuild, or use APP_UPDATE_CONFIG_URL for remote overrides

On this page