A crash on launch is the highest-severity rejection — the reviewer cannot evaluate any other part of the app. Apple tests on multiple OS versions and device types; an unhandled exception in root initialization code (unguarded useEffect, top-level JSON.parse, missing optional chaining) will crash on at least one configuration. CWE-390 (detection of error condition without action) and ISO 25010:2011 fault-tolerance both classify this as a fundamental reliability failure. One uncaught rejection in a startup async chain means the entire binary is rejected.
Critical because a launch crash makes the app completely unreviable — no functionality can be evaluated and rejection is immediate.
Add a root error boundary in App.tsx and wrap all startup async operations in try/catch.
// App.tsx
import { ErrorBoundary } from 'react-error-boundary';
export default function App() {
return (
<ErrorBoundary FallbackComponent={({ error }) => (
<View><Text>Something went wrong. Please restart the app.</Text></View>
)}>
<NavigationContainer>
<RootNavigator />
</NavigationContainer>
</ErrorBoundary>
);
}
For startup data fetching, always add a catch block: useEffect(() => { fetchConfig().catch(console.error); }, []). Test launch on the minimum supported OS version using Simulator (iOS) or AVD (Android) before every submission.
app-store-review-blockers.completeness-stability.no-crash-on-launchcriticaluseEffect on the root component; missing null checks on environment variables that are expected at startup; synchronous throws in module-level code (top-level JSON.parse() without try/catch, optional chaining missing on potentially undefined values); missing error boundaries at the root level. Check App.tsx (React Native/Expo), main.dart (Flutter), AppDelegate.swift (iOS), or MainActivity.kt (Android) for try/catch coverage of critical initialization. Also search for known crash-inducing patterns: calling navigation.navigate() before the navigator is ready, accessing AsyncStorage synchronously, or using deprecated APIs removed in the minimum supported OS version.ErrorBoundary (React Native) or equivalent (Flutter ErrorWidget.builder, iOS NSSetUncaughtExceptionHandler) is present to catch unexpected crashes gracefully."No root ErrorBoundary found — any uncaught exception will crash the app on launch" or "App.tsx has unhandled async initialization in useEffect with no catch block"// App.tsx
import { ErrorBoundary } from 'react-error-boundary';
export default function App() {
return (
<ErrorBoundary FallbackComponent={ErrorFallback}>
<NavigationContainer>...</NavigationContainer>
</ErrorBoundary>
);
}
useEffect async operations in try/catch?.) and nullish coalescing (??) defensively on all external data at startup