Skip to main content

🛠️ 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

yarn install Fails

Problem: yarn install fails with dependency conflicts or other errors. Solution: A clean reinstall often resolves dependency issues.
# Navigate to the root of your Shipnative project
cd shipnative

# Clear all caches and lock files
rm -rf node_modules
rm -rf apps/*/node_modules
rm yarn.lock

# Reinstall dependencies
yarn install

# If still encountering issues, try a forced reinstall
yarn install --force

TypeScript Errors After Fresh Install

Problem: After a fresh yarn install, TypeScript shows numerous errors in your IDE. Solution: This often happens when the TypeScript server needs to be refreshed.
# Navigate to the apps/app directory
cd apps/app

# Rebuild TypeScript (if applicable, though usually not needed for fresh install)
# yarn compile 

# Restart the TypeScript server in your VS Code (or other IDE)
# In VS Code: Cmd+Shift+P (macOS) or Ctrl+Shift+P (Windows/Linux) -> "TypeScript: Restart TS Server"

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:
  1. Check .env file location: The .env file should be located in the apps/app/ directory.
  2. Verify variable naming: All environment variables intended for Expo’s build process must start with EXPO_PUBLIC_. For example, EXPO_PUBLIC_SUPABASE_URL.
  3. Restart Metro Bundler: The Metro bundler caches environment variables. A full restart with cache clearing is often necessary.
    # Navigate to the root of your Shipnative project
    cd shipnative
    yarn app:start --clear
    
  4. Verify variables are loaded at runtime: Add a temporary console.log in your app’s entry point (e.g., App.tsx) to check if the variables are accessible.
    console.log('Supabase URL:', process.env.EXPO_PUBLIC_SUPABASE_URL);
    

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.
# Navigate to the root of your Shipnative project
cd shipnative

# Clear Metro cache
yarn app:start --clear

# Manually clear Expo and Metro caches
rm -rf apps/app/.expo
rm -rf apps/app/node_modules/.cache

# Kill any processes running on Metro's default port (8081)
lsof -ti:8081 | xargs kill -9

# Then try running your app again
yarn app:ios # or yarn app:android

”Unable to resolve module”

Problem: You see an error like Unable to resolve module @/components/Button or similar path resolution issues. Solution:
  1. Check tsconfig.json path mappings: Ensure your apps/app/tsconfig.json has correct paths configured for your aliases (e.g., @/*).
    {
      "compilerOptions": {
        "paths": {
          "@/*": ["./app/*"]
        }
      }
    }
    
  2. Clear Metro cache: Path changes often require a cache refresh.
    # Navigate to the root of your Shipnative project
    cd shipnative
    yarn app:start --clear
    
  3. 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.
# Clear Watchman cache (if installed)
watchman watch-del-all

# Clear Metro cache
yarn app:start --clear

# If the issue persists, check for actual duplicate files in your project
# find . -name "*.tsx" -o -name "*.ts" | sort | uniq -d

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:
# List available simulators to ensure one is recognized
xcrun simctl list devices

# If no simulator is booted, try booting a specific one (e.g., "iPhone 15 Pro")
xcrun simctl boot "iPhone 15 Pro"

# Then run your app again
yarn app:ios

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:
# List all available simulators with iOS versions
xcrun simctl list devices available

# Run with a specific simulator device name
cd apps/app
expo run:ios --simulator "iPhone 17 Pro"  # iOS 26.0

# Or use the device UDID for more precision
expo run:ios --simulator "D44A1507-3E39-4AA2-9662-F1CC7C832D68"

# You can also set an environment variable for all Expo commands
export EXPO_IOS_SIMULATOR_DEVICE_NAME="iPhone 17 Pro"
yarn ios
Note: The simulator version depends on your Xcode installation. To use iOS 26.0, ensure you have Xcode 16+ installed with the iOS 26.0 runtime downloaded.

”Command PhaseScriptExecution failed” (iOS)

Problem: iOS build fails during the CocoaPods installation or a PhaseScriptExecution step. Solution: This often indicates an issue with CocoaPods dependencies.
# Navigate to the iOS project directory
cd apps/app/ios

# Clean CocoaPods caches and reinstall
rm -rf Pods Podfile.lock
pod install --repo-update

# If still failing, try a full deintegrate and reinstall
pod deintegrate
pod install

# Then try building your app again from the root
cd ../..
yarn app:ios

White Screen on iOS

Problem: The app builds and launches on iOS, but you only see a blank white screen. Solution:
  1. Check console logs: The most common cause is a JavaScript error during app initialization.
    # View iOS device/simulator logs
    xcrun simctl spawn booted log stream --predicate 'processImagePath contains "your-app-bundle-id"'
    
  2. Common causes: Uncaught JavaScript errors, missing font loading, or issues with SafeAreaView setup.
  3. Debug: Add console.log statements in your App.tsx or 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 your ANDROID_HOME environment variable is set or create a local.properties file.
# Option 1: Set ANDROID_HOME environment variable (recommended)
export ANDROID_HOME=/Users/YOUR_USERNAME/Library/Android/sdk # Adjust path as needed
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/platform-tools

# Option 2: Create local.properties file
# Navigate to apps/app/android
cd apps/app/android
echo "sdk.dir=/Users/YOUR_USERNAME/Library/Android/sdk" > local.properties # Adjust path

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.
# Navigate to the Android project directory
cd apps/app/android

# Clean Gradle build
./gradlew clean

# Then try building your app again from the root
cd ../..
yarn app:android

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.
  1. Verify .env in production build: Ensure your build process correctly bundles or accesses your .env file for production. This often involves specific configurations in your CI/CD pipeline or EAS build profiles.
  2. Check environment variable prefix: Confirm all production API keys are prefixed with EXPO_PUBLIC_.
  3. Rebuild app: Ensure you perform a clean production build after verifying your environment setup.

Runtime Errors

Problem: “The action ‘NAVIGATE’ with payload containing name ‘Screen’ was not handled” or similar navigation issues. Solution:
  1. Check screen registration: Ensure the target screen is correctly registered within your expo-router configuration or React Navigation stack.
  2. Verify screen name: Screen names are case-sensitive and must match exactly.
  3. 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 setState directly within a component’s render function.
  • Missing dependencies in a useEffect hook, causing it to run on every render.
  • Creating new objects or arrays in the render function that are used as dependencies for hooks.
Solution: Review your component’s lifecycle and hook dependencies.
// ❌ BAD: Infinite loop
const MyComponent = () => {
  const [count, setCount] = useState(0)
  setCount(count + 1) // This will cause an infinite re-render!
  return <View />
}

// ✅ GOOD: Update state in a controlled manner (e.g., in useEffect or event handler)
const MyComponent = () => {
  const [count, setCount] = useState(0)
  useEffect(() => {
    setCount(count + 1) // Runs only once on mount
  }, []) 
  return <View />
}

Authentication Loop

Problem: The app repeatedly redirects between login and home screens, or gets stuck in an authentication loop. Solution:
  1. Auth state persistence: Ensure your authentication state (e.g., from Supabase) is correctly persisted across app restarts (e.g., using SecureStore). Check your useAuthStore implementation for persistence configuration.
  2. 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. Use useEffect or a dedicated authentication flow handler.

Subscription Purchase Fails

Problem: RevenueCat purchase flows do not complete successfully. Solution:
  1. 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.
  2. Testing: Test purchases in sandbox mode (iOS) or with test accounts (Android) as described in the Payments guide.
  3. Check Logs: Add console.log statements 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:
[StoreKit] Error enumerating unfinished transactions: Error Domain=ASDErrorDomain Code=509 "No active account"
Solution: These errors are EXPECTED and HARMLESS in the iOS simulator. They occur because:
  1. No Apple ID signed in: The simulator doesn’t have an active Apple ID, so StoreKit can’t enumerate transactions.
  2. Normal behavior: This is how StoreKit behaves when there’s no account - it’s not a bug.
  3. Doesn’t affect functionality: RevenueCat will still work correctly. When you test purchases, you’ll be prompted to sign in with a sandbox account.
What to do:
  • 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).
Note: These are native iOS logs that can’t be filtered by RevenueCat’s log handler. They’re part of StoreKit’s normal operation and don’t indicate any configuration issues.

Performance Concerns

App Starts Slowly

Problem: Your app takes a long time (e.g., >5 seconds) to load on startup. Solutions:
  1. Profile Startup: Use tools like console.time or Performance.mark to identify bottlenecks during app initialization.
  2. Lazy Load Screens/Components: Defer loading of non-essential screens or components until they are needed.
    // Example: Lazy load a screen (if using React.lazy with a compatible bundler)
    // const ProfileScreen = lazy(() => import('./screens/ProfileScreen'))
    
  3. 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.
<FlatList
  data={items}
  renderItem={renderItem}
  keyExtractor={(item) => item.id.toString()} // Must be a string
  removeClippedSubviews={true} // Unmounts items that are off-screen
  maxToRenderPerBatch={10} // Number of items to render per batch
  updateCellsBatchingPeriod={50} // Delay between rendering batches
  initialNumToRender={10} // Number of items to render initially
  windowSize={5} // Number of items rendered outside of the visible area
/>
  • Memoize renderItem: Use useCallback to prevent renderItem from being recreated on every render.
    const renderItem = useCallback(({ item }) => (
      <ItemComponent item={item} />
    ), [])
    
  • Memoize List Items: Use React.memo for individual list item components to prevent unnecessary re-renders.
    const ItemComponent = React.memo(({ item }) => {
      return <View>{/* ... item content ... */}</View>
    })
    

Large Bundle Size

Problem: Your app’s final bundle size is excessively large (e.g., >50MB). Solution:
  1. Analyze Bundle: Use tools like yarn dlx react-native-bundle-visualizer (or npx react-native-bundle-visualizer) to visualize your bundle and identify large contributors.
  2. Remove Unused Dependencies: Regularly audit your package.json and remove libraries you no longer use.
  3. Use Smaller Alternatives: Opt for lightweight libraries (e.g., date-fns instead of moment, zustand instead of Redux for simple state).
  4. 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:
  1. Restart TS Server: In VS Code, open the Command Palette (Cmd/Ctrl+Shift+P) and search for “TypeScript: Restart TS Server”.
  2. Use Workspace TypeScript Version: Ensure VS Code is using the TypeScript version from your project’s node_modules rather than its built-in version.
  3. 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:
  1. 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).
  2. 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.
  3. 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:
  1. Enable Fast Refresh: On your device/simulator, shake it to open the developer menu and ensure “Enable Fast Refresh” is toggled on.
  2. Restart Packager: A full restart of the Metro bundler often resolves this.
    yarn app:start --clear
    
  3. 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:
  1. Expo Documentation: The official Expo documentation is an excellent resource for all things Expo and React Native.
  2. 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.
  3. Community Forums/Discord: Engage with the broader Expo and React Native communities.
  4. Sentry Dashboard: If the issue is a production error, check your Sentry dashboard for detailed error reports and stack traces.
  5. Enable Verbose Logging: For more detailed output, run your app with verbose logging enabled:
    EXPO_DEBUG=true yarn app:ios # or yarn app:android
    

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.