Skip to content

Fabric Unmount Crash (-[RCTViewComponentView unmountChildComponentView:index:]) when using unstable-native-tabs on iOS 27 Beta #4197

Description

@darshanraashmi

Description

After resolving the initial launch crash, the app successfully booted, but crashed with a fatal EXC_CRASH (SIGABRT) whenever the app attempted to mount or unmount Expo Router's Native Tabs (expo-router/unstable-native-tabs).

Crash Stack Trace Highlight:

text

Thread 0 Crashed
-[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:] + 268
-[RCTViewComponentView unmountChildComponentView:index:] + 2476
RCTPerformMountInstructions

Steps to reproduce

This is a crash occurring deep inside React Native's New Architecture (Fabric) rendering engine. unstable-native-tabs uses react-native-screens under the hood to interface with the native iOS UITabBarController.

On iOS 27 Beta, when navigating or conditionally rendering these native tabs, the native view hierarchy managed by react-native-screens falls out of sync with Fabric's shadow tree. When Fabric issues the RCTPerformMountInstructions to unmount a child view, the native RCTViewComponentView fails an assertion because the view it is trying to unmount is in an unexpected state, triggering the SIGABRT.

How We Solved It (The Workaround)
Since this is a deep native bug between Fabric and react-native-screens on the iOS 27 Beta SDK, we bypassed the buggy native code entirely at the JavaScript level.

We added a platform and version check in our router configuration (app-navigator.tsx and _layout.tsx). If the device is running iOS 27, we dynamically skip rendering the (which triggers NativeTabs) and instead fall back to our custom JavaScript-based @react-navigation/bottom-tabs.

Our Code Solution:

javascript

const IS_IOS = Platform.OS === 'ios';
const iosVersion = parseInt(String(Platform.Version), 10);
// iOS 27 Beta causes react-native-screens to crash in Fabric on unmount.
const IOS_27_BETA_BROKEN = iosVersion === 27;
// iOS 18+ uses NativeTabs. iOS < 18 (and iOS 27 Beta) use the custom JS tab bar fallback.
if (IS_IOS && iosVersion >= 26 && !IOS_27_BETA_BROKEN) {
return ;
}
This avoids invoking the native UITabBarController bridging on iOS 27, keeping the app stable while still giving iOS 18+ users the premium native tabs experience.

Snack or a link to a repository

Since this involves a deep native Fabric crash on a beta iOS version, a Snack cannot reproduce it (Snack does not support New Architecture on iOS 27 beta). However, any standard Expo project using Expo Router's unstable-native-tabs on iOS 27 beta with the New Architecture enabled will reproduce this.

Screens version

4.23.0

React Native version

0.83.6

Platforms

iOS

JavaScript runtime

Hermes

Workflow

Expo managed workflow

Architecture

Fabric (New Architecture)

Build type

Debug mode

Device

Real device

Device model

iPhone 17 Pro Max, iOS 27 beta, Xcode 27 beta

Acknowledgements

Yes

Metadata

Metadata

Assignees

Labels

close-when-staleThis issue is going to be closed when there is no activity for a whilemissing-reproThis issue need minimum repro scenarioplatform:iosIssue related to iOS part of the library

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions