🛠️ Troubleshooting
Encountering issues during development is a normal part of the process. This guide provides solutions to common problems you might face while working with Shipnative.Table of Contents
- Setup and Installation Issues
- Environment Variable Problems
- Metro Bundler Errors
- Platform-Specific Build Issues
- Mock Mode Behavior
- Runtime Errors
- Performance Concerns
- Development Tooling
- Getting Help
Setup and Installation Issues
yarn install Fails
Problem: yarn install fails with dependency conflicts or other errors.
Solution:
A clean reinstall often resolves dependency issues.
TypeScript Errors After Fresh Install
Problem: After a freshyarn install, TypeScript shows numerous errors in your IDE.
Solution:
This often happens when the TypeScript server needs to be refreshed.
Environment Variable Problems
Environment Variables Not Loading / Mock Mode Active Unexpectedly
Problem: Your app runs in mock mode even after configuring API keys in your.env file, or environment variables are not accessible.
Solution:
- Check
.envfile location: The.envfile should be located in theapps/app/directory. - Verify variable naming: All environment variables intended for Expo’s build process must start with
EXPO_PUBLIC_. For example,EXPO_PUBLIC_SUPABASE_URL. - Restart Metro Bundler: The Metro bundler caches environment variables. A full restart with cache clearing is often necessary.
- Verify variables are loaded at runtime: Add a temporary
console.login your app’s entry point (e.g.,App.tsx) to check if the variables are accessible.
Metro Bundler Errors
Metro Won’t Start
Problem:yarn app:ios or yarn app:android fails with a “Metro bundler error” or similar message, preventing the app from launching.
Solution:
Clear Metro’s cache and ensure no other process is using its default port.
”Unable to resolve module”
Problem: You see an error likeUnable to resolve module @/components/Button or similar path resolution issues.
Solution:
- Check
tsconfig.jsonpath mappings: Ensure yourapps/app/tsconfig.jsonhas correctpathsconfigured for your aliases (e.g.,@/*). - Clear Metro cache: Path changes often require a cache refresh.
- Verify file existence: Double-check that the module you’re trying to import actually exists at the specified path.
Haste Module Map Collision
Problem: An error indicating “Duplicated files or mocks” or a “Haste module map collision.” Solution: This usually means Metro’s internal module map is corrupted or has conflicting entries.Platform-Specific Build Issues
iOS Simulator Won’t Launch
Problem:yarn app:ios builds successfully, but the iOS simulator doesn’t open or the app doesn’t launch on it.
Solution:
Using a Specific iOS Simulator Version
Problem: You want to use a specific iOS simulator version (e.g., iOS 26.0). Solution: Expo will automatically use the default simulator, but you can specify a specific device:”Command PhaseScriptExecution failed” (iOS)
Problem: iOS build fails during the CocoaPods installation or aPhaseScriptExecution step.
Solution:
This often indicates an issue with CocoaPods dependencies.
White Screen on iOS
Problem: The app builds and launches on iOS, but you only see a blank white screen. Solution:- Check console logs: The most common cause is a JavaScript error during app initialization.
- Common causes: Uncaught JavaScript errors, missing font loading, or issues with
SafeAreaViewsetup. - Debug: Add
console.logstatements in yourApp.tsxor root component to pinpoint where the app is failing to render.
Android “SDK location not found”
Problem: Android build fails with an error indicating the Android SDK location could not be found. Solution: Ensure yourANDROID_HOME environment variable is set or create a local.properties file.
Gradle Build Fails (Android)
Problem: Android build fails with a Gradle error like “Could not resolve all files for configuration.” Solution: Clean your Gradle build caches.Mock Mode Behavior
Mock Mode Activates in Production
Problem: Your production build unexpectedly uses mock services instead of real backend services. Solution: This indicates that your production environment is not correctly loading your API keys.- Verify
.envin production build: Ensure your build process correctly bundles or accesses your.envfile for production. This often involves specific configurations in your CI/CD pipeline or EAS build profiles. - Check environment variable prefix: Confirm all production API keys are prefixed with
EXPO_PUBLIC_. - Rebuild app: Ensure you perform a clean production build after verifying your environment setup.
Runtime Errors
Navigation Errors
Problem: “The action ‘NAVIGATE’ with payload containing name ‘Screen’ was not handled” or similar navigation issues. Solution:- Check screen registration: Ensure the target screen is correctly registered within your
expo-routerconfiguration or React Navigation stack. - Verify screen name: Screen names are case-sensitive and must match exactly.
- Nesting: Confirm that your navigators are correctly nested and that you are attempting to navigate within the correct navigator context.
”Maximum update depth exceeded”
Problem: Your app crashes with an error indicating “Maximum update depth exceeded,” typically caused by an infinite re-render loop. Common Causes:- Calling
setStatedirectly within a component’s render function. - Missing dependencies in a
useEffecthook, causing it to run on every render. - Creating new objects or arrays in the render function that are used as dependencies for hooks.
Authentication Loop
Problem: The app repeatedly redirects between login and home screens, or gets stuck in an authentication loop. Solution:- Auth state persistence: Ensure your authentication state (e.g., from Supabase) is correctly persisted across app restarts (e.g., using SecureStore). Check your
useAuthStoreimplementation for persistence configuration. - Navigation logic: Avoid performing conditional navigation (e.g.,
router.replace('/login')) directly within a component’s render function without proper checks for authentication status and loading states. UseuseEffector a dedicated authentication flow handler.
Subscription Purchase Fails
Problem: RevenueCat purchase flows do not complete successfully. Solution:- RevenueCat Configuration:
- Verify your RevenueCat API keys are correct in
apps/app/.env. - Ensure entitlements and products are correctly set up in the RevenueCat dashboard and linked to your app store products.
- Verify your RevenueCat API keys are correct in
- Testing: Test purchases in sandbox mode (iOS) or with test accounts (Android) as described in the Payments guide.
- Check Logs: Add
console.logstatements around your purchase logic to capture any errors returned by RevenueCat.
StoreKit “No Active Account” Errors (iOS Simulator)
Problem: You see errors in your console like:- No Apple ID signed in: The simulator doesn’t have an active Apple ID, so StoreKit can’t enumerate transactions.
- Normal behavior: This is how StoreKit behaves when there’s no account - it’s not a bug.
- Doesn’t affect functionality: RevenueCat will still work correctly. When you test purchases, you’ll be prompted to sign in with a sandbox account.
- ✅ Ignore these errors - they’re informational, not breaking errors.
- ✅ Test purchases normally - when you attempt a purchase, you’ll sign in with a sandbox tester account.
- ✅ Use a real device if you want to avoid these logs (they won’t appear on devices with an active Apple ID).
Performance Concerns
App Starts Slowly
Problem: Your app takes a long time (e.g., >5 seconds) to load on startup. Solutions:- Profile Startup: Use tools like
console.timeorPerformance.markto identify bottlenecks during app initialization. - Lazy Load Screens/Components: Defer loading of non-essential screens or components until they are needed.
- Reduce Initial Bundle Size:
- Analyze your bundle to identify large dependencies.
- Use smaller alternative libraries where possible.
- Optimize assets (e.g., compress images, use appropriate formats).
Slow List Scrolling
Problem:FlatList or SectionList components scroll slowly or drop frames, leading to a choppy user experience.
Solution:
Optimize your list components using React Native’s built-in performance props and memoization.
- Memoize
renderItem: UseuseCallbackto preventrenderItemfrom being recreated on every render. - Memoize List Items: Use
React.memofor individual list item components to prevent unnecessary re-renders.
Large Bundle Size
Problem: Your app’s final bundle size is excessively large (e.g., >50MB). Solution:- Analyze Bundle: Use tools like
yarn dlx react-native-bundle-visualizer(ornpx react-native-bundle-visualizer) to visualize your bundle and identify large contributors. - Remove Unused Dependencies: Regularly audit your
package.jsonand remove libraries you no longer use. - Use Smaller Alternatives: Opt for lightweight libraries (e.g.,
date-fnsinstead ofmoment,zustandinstead of Redux for simple state). - Optimize Assets: Ensure images and other media assets are optimized for mobile.
Development Tooling
VS Code TypeScript Not Working
Problem: VS Code shows incorrect TypeScript errors or doesn’t provide proper type inference. Solution:- Restart TS Server: In VS Code, open the Command Palette (Cmd/Ctrl+Shift+P) and search for “TypeScript: Restart TS Server”.
- Use Workspace TypeScript Version: Ensure VS Code is using the TypeScript version from your project’s
node_modulesrather than its built-in version. - Reload Window: Sometimes a full window reload (Cmd/Ctrl+Shift+P -> “Developer: Reload Window”) is necessary.
Debugger Won’t Connect
Problem: React Native Debugger, Chrome DevTools, or Flipper won’t connect to your running app. Solution:- Enable Remote Debugging: On your device/simulator, shake it to open the developer menu and enable “Debug Remote JS” (for Chrome DevTools) or “Open Expo Dev Tools” (for Expo’s web-based debugger).
- Use Flipper (Recommended): Flipper is a powerful debugging platform for React Native.
- Install Flipper:
brew install --cask flipper(macOS) or follow instructions on fbflipper.com. - Ensure your app is running and Flipper is open.
- Install Flipper:
- Check Ports: Ensure no other applications are blocking the default debugging ports (e.g., 19000-19003 for Expo, 8081 for Metro).
Hot Reload Not Working
Problem: Changes to your code are not automatically reflecting in the app (Fast Refresh is not working). Solution:- Enable Fast Refresh: On your device/simulator, shake it to open the developer menu and ensure “Enable Fast Refresh” is toggled on.
- Restart Packager: A full restart of the Metro bundler often resolves this.
- Save Files: Ensure your IDE is saving files correctly after changes.
Getting Help
If you’ve tried the solutions above and are still stuck, here are some resources to help you:- Expo Documentation: The official Expo documentation is an excellent resource for all things Expo and React Native.
- GitHub Issues: Search the Shipnative GitHub repository for similar issues, or open a new one if you can’t find a solution. Provide as much detail as possible.
- Community Forums/Discord: Engage with the broader Expo and React Native communities.
- Sentry Dashboard: If the issue is a production error, check your Sentry dashboard for detailed error reports and stack traces.
- Enable Verbose Logging: For more detailed output, run your app with verbose logging enabled:
Prevention Tips
- Always use TypeScript: Catches many errors before runtime.
- Test in mock mode first: Faster iteration and isolation of frontend issues.
- Clear cache regularly: Prevents stale data and unexpected behavior.
- Keep dependencies updated: Stay current with security patches and bug fixes.
- Monitor Sentry: Proactively identify and address production errors.
- Read logs carefully: Error messages often contain crucial clues.