diff --git a/apps/mobile/src/features/review/ReviewSheet.tsx b/apps/mobile/src/features/review/ReviewSheet.tsx index 0524371738fb..98bb72f1fbaf 100644 --- a/apps/mobile/src/features/review/ReviewSheet.tsx +++ b/apps/mobile/src/features/review/ReviewSheet.tsx @@ -398,7 +398,11 @@ export function ReviewSheet(props: ReviewSheetProps) { selectedSection, draftMessage, }); - const NativeReviewDiffView = resolveNativeReviewDiffView()!; + // Resolution returns null while Expo registers the native view (or forever + // when the binary lacks it). Rendering a null component type crashes the + // app, so callers must fall back — ThreadFeed's ReviewCommentCard does the + // same check. + const NativeReviewDiffView = resolveNativeReviewDiffView(); const nativeReviewDiffViewRef = useRef(null); const showcasedReviewDrawRef = useRef(null); // Native pull-to-refresh on the diff surface (replaces the old Refresh menu item). @@ -780,7 +784,7 @@ export function ReviewSheet(props: ReviewSheetProps) { onRetry={handleRetryEnvironment} /> - ) : selectedSection && parsedDiff.kind === "files" ? ( + ) : selectedSection && parsedDiff.kind === "files" && NativeReviewDiffView ? ( + ) : parsedDiff.kind === "files" ? ( + // The native diff surface could not be resolved on this binary; + // degrade to the raw patch instead of crashing the app. + + + Native diff view unavailable. Showing the raw patch. + + + + {selectedSection?.diff ?? ""} + + + ) : null} )}