Skip to content

Fix debug Buy scene crash on amount entry (RN attributed-string hash) - #6224

Merged
j0ntz merged 1 commit into
developfrom
jon/fix-buy-text-measure-crash
Sep 28, 2026
Merged

j0ntz merged 1 commit into
developfrom
jon/fix-buy-text-measure-crash

Conversation

@j0ntz

@j0ntz j0ntz commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

Description

Asana task

Debug builds on the iOS simulator abort with SIGABRT when an amount is typed on the Buy scene. The crash is in React Native's text-measure cache: safe_assert_terminate in EvictingCacheMap<AttributedString>::find, reached from RCTTextLayoutManager measuring the TextInput.

Root cause: React Native 0.79.2 hashes an AttributedString::Fragment by its whole parent ShadowView (props, event emitter and state pointers), but fragment equality compares only the parent tag and layout metrics. Two equal attributed strings can land in different hash buckets. folly's F14 fallback set then finds the equal key by linear scan on a small cache (3 entries or fewer) and trips FOLLY_SAFE_DCHECK, which is compiled only into debug builds.

This backports the upstream fix from facebook/react-native#50147 (shipped in 0.80.0, not in any 0.79.x release) into the existing patches/react-native+0.79.2.patch:

  • the fragment hash uses the parent tag instead of the whole ShadowView
  • the AttributedString hash and equality both include the base text attributes

TextAttributes equality and hash already cover textAlignVertical in 0.79.2, so that part of the upstream change is not needed. The upstream operator!= removals are a C++20 cleanup and are left out.

Testing on the iOS simulator. Each entry logs in, opens Buy, types exactly 500 USD and holds for the quote while a liveness check runs:

Build Entries Crashes
develop, Debug (baseline), 1 Hz hierarchy poll 20 10
this branch, Debug, 1 Hz hierarchy poll (400 polls) 20 0
this branch, Debug, no poll 20 0
develop code, Debug, keypad dismissed after the amount 10 2
this branch, Debug, keypad dismissed after the amount 10 0
develop code, Release, 1 Hz hierarchy poll 20 0
  • Baseline: every crash hit right after the amount was entered, and all retained crash reports carry the same stack. Some baseline entries typed "500,500" instead of 500 because the scene restores the previous amount; the fixed runs clear the field first.
  • Keypad dismissal: Maestro's hideKeyboard cannot close the decimal pad on its own, so these entries run hideKeyboard and then tap the keypad's Done bar, and the final frame shows the keypad closed. On develop code both crashes came during that dismissal, with the same stack as the baseline. On this branch the Done tap succeeded in all 10 entries with no crash.
  • Release: the unfixed Release build did not crash. The assertion is compiled out of Release builds, so production is not affected; there the mismatch only costs cache misses.

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Requirements

If you have made any visual changes to the GUI. Make sure you have:

  • Tested on iOS device
  • Tested on Android device
  • Tested on small-screen device (iPod Touch)
  • Tested on large-screen device (tablet)

Note

Low Risk
Native renderer patch only; production Release is unaffected, and the change aligns hash with equality rather than altering app business logic.

Overview
Fixes iOS Debug crashes when entering a buy amount by extending patches/react-native+0.79.2.patch with the upstream React Native fix (facebook/react-native#50147): AttributedString equality and hashing now stay aligned (fragment hash uses the parent shadow tag instead of the whole ShadowView, and base text attributes participate in hash and operator==). That stops the text-measurement cache from tripping a debug-only Folly assertion during TextInput layout on the Buy scene.

The same patch hunk also caps shadow-tree commit retries (MAX_COMMIT_ATTEMPTS_BEFORE_LOCKING) and routes commit locking through helper lock types—matching more of the upstream 0.80 renderer changes bundled with this backport.

CHANGELOG: adds an Unreleased note for the iOS debug Buy amount-entry crash. Release builds are unchanged (assertions compiled out); impact is developer/simulator stability and slightly better cache behavior in production.

Reviewed by Cursor Bugbot for commit 417ac87. Bugbot is set up for automated code reviews on this repo. Configure here.

Test evidence

359f0aa
Backport RN attributed-string hash fix
2026-09-27

1. fixed debug buy 500 quote under polling

2. fixed debug buy 500 quote unpolled

3. unfixed release buy 500 no crash

4. fixed debug buy 500 keyboard dismissed

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

Claude Code Review is paused for this repository. To reconnect it, an admin of this repository's GitHub organization (or the account owner, for personal repositories) who can also manage your Claude organization's Code Review settings needs to re-link GitHub in Code Review settings. This is a one-time step.

Tip: disable this comment in your organization's Code Review settings.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Debug builds abort in the TextInput measure cache on the Buy scene.
React Native 0.79.2 hashes an AttributedString::Fragment by its whole
parent ShadowView (props, event emitter and state pointers), while
equality compares only the tag and layout metrics. Two equal strings
can then land in different buckets, and folly's F14 fallback set trips
a debug-only FOLLY_SAFE_DCHECK when it finds the equal key by linear
scan on a small cache.

Backport the hash and equality changes from upstream
react/react-native#50147 (in 0.80.0): hash the parent tag instead
of the whole ShadowView, and include the base text attributes in both
the AttributedString hash and equality. TextAttributes equality
already covers textAlignVertical in 0.79.2, so that part of the
upstream change is not needed.
@j0ntz
j0ntz force-pushed the jon/fix-buy-text-measure-crash branch from 359f0aa to 417ac87 Compare September 28, 2026 22:09

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

Claude Code Review is paused for this repository. To reconnect it, an admin of this repository's GitHub organization (or the account owner, for personal repositories) who can also manage your Claude organization's Code Review settings needs to re-link GitHub in Code Review settings. This is a one-time step.

Tip: disable this comment in your organization's Code Review settings.

@j0ntz
j0ntz enabled auto-merge September 28, 2026 22:17
@j0ntz
j0ntz merged commit 8c97ee9 into develop Sep 28, 2026
7 checks passed
@j0ntz
j0ntz deleted the jon/fix-buy-text-measure-crash branch September 28, 2026 22:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants