Skip to content

Crash measuring a Text that holds a View under strict layout conformance with enableFlexboxAutoMinSizeInStrictMode #59678

Open

Description

@YevheniiKotyrlo

Description

With enableFlexboxAutoMinSizeInStrictMode on, a screen under <experimental_LayoutConformance mode="strict"> that holds a Text with a View inside it crashes on the JavaScript thread once a later commit lays the screen out again while the Text stays as an earlier commit laid it out. With the flag off, the same app runs.

Every crash is under Yoga's computeMinContentMainSize, which walks a flex item's children without cloning them, so it measures the Paragraph of the committed tree. That Paragraph's cached content still points at the inline View its own layout replaced with a laid-out clone, and React's reference followed the clone, so the View is freed by then. Reading it faults in __dynamic_cast at 0xfffffffffffffff0, or recurses through the attachment's layout until the JavaScript thread's stack overflows.

I reproduced it on iOS with the reproducer below, on main (0.89.0-nightly-20261030-4afc5d5b9, 2 of 3 launches) and on 0.88.1 (3 of 3). The reproducer turns the flag on for iOS only; I have seen the same __dynamic_cast crash under computeMinContentMainSize on Android 16 in another app with this layout.

Steps to reproduce

  1. Clone https://github.com/YevheniiKotyrlo/rn-min-content-paragraph-crash. Its App.tsx renders, under <experimental_LayoutConformance mode="strict">, a ScrollView of pressable Texts that each hold a View of two Texts, and changes the height of a header above the list on each of 120 renders after mount. ios/ReproducerApp/FeatureFlags.mm turns enableFlexboxAutoMinSizeInStrictMode on over the Stable release level's overrides, once RCTReactNativeFactory has started.
  2. In ReproducerApp, run yarn install, then bundle install and bundle exec pod install in ios.
  3. Build it in Release and run it on an iPhone: npx react-native run-ios --mode Release --device.
  4. The app dies within a second of launch, while the header changes height. Expected: the list renders and stays.

React Native Version

0.89.0-nightly-20261030-4afc5d5b9, and 0.88.1

Affected Platforms

Runtime - iOS, Runtime - Android

Output of npx @react-native-community/cli info

System:
  OS: macOS 27.0.1
  CPU: (8) arm64 Apple M1
  Memory: 67.98 MB / 8.00 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 26.12.1
    path: /Users/yevhenii/.nvm/versions/node/v26.12.1/bin/node
  Yarn: Not Found
  npm:
    version: 12.2.1
    path: /Users/yevhenii/.nvm/versions/node/v26.12.1/bin/npm
  Watchman:
    version: 2026.10.19.00
    path: /opt/homebrew/bin/watchman
Managers:
  CocoaPods:
    version: 1.17.0
    path: /opt/homebrew/bin/pod
SDKs:
  iOS SDK:
    Platforms:
      - DriverKit 27.0
      - iOS 27.1
      - macOS 27.0
      - tvOS 27.0
      - visionOS 27.0
      - watchOS 27.0
  Android SDK: Not Found
IDEs:
  Android Studio: Not Found
  Xcode:
    version: 27.1/27A9275
    path: /usr/bin/xcodebuild
Languages:
  Java: Not Found
  Ruby:
    version: 4.0.9
    path: /opt/homebrew/bin/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react: Not Found
  react-native: Not Found
  react-native-macos: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: Not found
  newArchEnabled: Not found
iOS:
  hermesEnabled: Not found
  newArchEnabled: Not found

I ran it beside the reproducer's package.json on the Mac that built it, without its node_modules; the reproducer installs react 19.3.0, react-native 0.89.0-nightly-20261030-4afc5d5b9 and @react-native-community/cli 21.0.0-alpha.1. The device is an iPhone 12 Pro Max on iOS 27.0.1.

Stacktrace or Logs

On main, launch 1, the JavaScript thread (EXC_BAD_ACCESS, SIGBUS, "Thread stack size exceeded due to excessive recursion"):

 0 facebook::react::ShadowNode::ShadowNode(facebook::react::ShadowNode const&, facebook::react::ShadowNodeFragment const&)
 1 facebook::react::LayoutableShadowNode::LayoutableShadowNode(facebook::react::ShadowNode const&, facebook::react::ShadowNodeFragment const&)
 2 facebook::react::YogaLayoutableShadowNode::YogaLayoutableShadowNode(facebook::react::ShadowNode const&, facebook::react::ShadowNodeFragment const&)
 3 facebook::react::ConcreteComponentDescriptor<facebook::react::LayoutConformanceShadowNode>::cloneShadowNode(facebook::react::ShadowNode const&, facebook::react::ShadowNodeFragment const&) const
 4 facebook::react::ShadowNode::clone(facebook::react::ShadowNodeFragment const&) const
 5 facebook::react::YogaLayoutableShadowNode::cloneChildInPlace(unsigned long)
 6 facebook::react::YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector(YGNode const*, YGNode const*, unsigned long)
 7 facebook::yoga::Config::cloneNode(YGNode const*, YGNode const*, unsigned long) const
 8 facebook::yoga::Node::cloneChildrenIfNeeded()
 9 facebook::yoga::calculateLayoutImpl(facebook::yoga::Node*, float, float, facebook::yoga::Direction, facebook::yoga::SizingMode, facebook::yoga::SizingMode, float, float, bool, facebook::yoga::LayoutPassReason, facebook::yoga::LayoutData&, unsigned int, unsigned int)
10 facebook::yoga::calculateLayoutInternal(facebook::yoga::Node*, float, float, facebook::yoga::Direction, facebook::yoga::SizingMode, facebook::yoga::SizingMode, float, float, bool, facebook::yoga::LayoutPassReason, facebook::yoga::LayoutData&, unsigned int, unsigned int)
11 facebook::yoga::calculateLayout(facebook::yoga::Node*, float, float, facebook::yoga::Direction)
12 facebook::react::YogaLayoutableShadowNode::layoutTree(facebook::react::LayoutContext, facebook::react::LayoutConstraints)
13 facebook::react::LayoutableShadowNode::measure(facebook::react::LayoutContext const&, facebook::react::LayoutConstraints const&) const
14 facebook::react::ParagraphShadowNode::getContentWithMeasuredAttachments(facebook::react::LayoutContext const&, facebook::react::LayoutConstraints const&) const
15 facebook::react::ParagraphShadowNode::measureContent(facebook::react::LayoutContext const&, facebook::react::LayoutConstraints const&) const
16 facebook::react::YogaLayoutableShadowNode::yogaNodeMeasureCallbackConnector(YGNode const*, float, YGMeasureMode, float, YGMeasureMode)
17 facebook::yoga::Node::measure(float, facebook::yoga::MeasureMode, float, facebook::yoga::MeasureMode)
18 facebook::yoga::computeMinContentMainSize(facebook::yoga::Node*, facebook::yoga::FlexDirection, facebook::yoga::Direction, float, float, unsigned int)
19 facebook::yoga::computeMinContentMainSize(facebook::yoga::Node*, facebook::yoga::FlexDirection, facebook::yoga::Direction, float, float, unsigned int)
20 facebook::yoga::computeMinContentMainSize(facebook::yoga::Node*, facebook::yoga::FlexDirection, facebook::yoga::Direction, float, float, unsigned int)
21 facebook::yoga::computeMinContentMainSize(facebook::yoga::Node*, facebook::yoga::FlexDirection, facebook::yoga::Direction, float, float, unsigned int)
22 facebook::yoga::calculateLayoutImpl(facebook::yoga::Node*, float, float, facebook::yoga::Direction, facebook::yoga::SizingMode, facebook::yoga::SizingMode, float, float, bool, facebook::yoga::LayoutPassReason, facebook::yoga::LayoutData&, unsigned int, unsigned int)

On 0.88.1, one of the launches (EXC_BAD_ACCESS, SIGSEGV, KERN_INVALID_ADDRESS at 0xfffffffffffffff0):

 0 __cxxabiv1::(anonymous namespace)::dyn_cast_get_derived_info(__cxxabiv1::(anonymous namespace)::derived_object_info*, void const*)
 1 __dynamic_cast
 2 facebook::react::ParagraphShadowNode::measureContent(facebook::react::LayoutContext const&, facebook::react::LayoutConstraints const&) const
 3 facebook::react::YogaLayoutableShadowNode::yogaNodeMeasureCallbackConnector(YGNode const*, float, YGMeasureMode, float, YGMeasureMode)
 4 facebook::yoga::Node::measure(float, facebook::yoga::MeasureMode, float, facebook::yoga::MeasureMode)
 5 facebook::yoga::computeMinContentMainSize(facebook::yoga::Node*, facebook::yoga::FlexDirection, facebook::yoga::Direction, float, float)
 6 facebook::yoga::computeMinContentMainSize(facebook::yoga::Node*, facebook::yoga::FlexDirection, facebook::yoga::Direction, float, float)
 7 facebook::yoga::computeMinContentMainSize(facebook::yoga::Node*, facebook::yoga::FlexDirection, facebook::yoga::Direction, float, float)
 8 facebook::yoga::computeMinContentMainSize(facebook::yoga::Node*, facebook::yoga::FlexDirection, facebook::yoga::Direction, float, float)
 9 facebook::yoga::calculateLayoutImpl(facebook::yoga::Node*, float, float, facebook::yoga::Direction, facebook::yoga::SizingMode, facebook::yoga::SizingMode, float, float, bool, facebook::yoga::LayoutPassReason, facebook::yoga::LayoutData&, unsigned int, unsigned int)

MANDATORY Reproducer

https://github.com/YevheniiKotyrlo/rn-min-content-paragraph-crash

Screenshots and Videos

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions