Sentry
https://expensify.sentry.io/issues/APP-KDF
Impact (snapshot at filing)
- Users (total since first seen): 37
- Events: 42
- Users (last 14d): 37
- First seen: 2026-08-24 (Sentry substatus is still
new)
- Last seen: ongoing
- Platform: iOS HybridApp
- App version(s): 9.4.56-3, 9.4.57-3, 9.4.58-4, 9.4.59-5, 9.4.60-2
- Mechanism:
AppHang (Fatal App Hang Fully Blocked)
- Culprit:
-[RCTMarkdownUtils applyMarkdownFormatting:withDefaultTextAttributes:markdownStyle:parserId:]
Every affected user in the 14 day window is a new user of this signature, so this is a fresh
regression rather than a long tail.
Stack trace (top frames, main thread)
__ulock_wait2
_os_unfair_lock_lock_slow
objc_sync_enter
-[RCTMarkdownUtils applyMarkdownFormatting:withDefaultTextAttributes:markdownStyle:parserId:]
facebook::react::MarkdownTextInputDecoratorShadowNode::applyMarkdownFormattingToTextInputState
facebook::react::MarkdownTextInputDecoratorShadowNode::measureContent
facebook::react::MarkdownTextInputDecoratorShadowNode::yogaNodeMeasureCallbackConnector
facebook::yoga::Node::measure (Node.cpp:59)
facebook::yoga::measureNodeWithMeasureFunc (CalculateLayout.cpp:356)
facebook::yoga::calculateLayoutImpl (CalculateLayout.cpp:1349)
... ~100 further Yoga frames: calculateLayoutInternal / calculateLayoutImpl /
computeFlexBasisForChild / resolveFlexibleLength / layoutAbsoluteDescendants ...
facebook::react::YogaLayoutableShadowNode::layoutTree (YogaLayoutableShadowNode.cpp:683)
The event also shows LiveMarkdownRuntime_queue and LiveMarkdownRuntime(timeout) threads alive
while the main thread sits in the lock.
Suspected cause
The Yoga measure callback for MarkdownTextInputDecoratorShadowNode calls
applyMarkdownFormatting synchronously on the main thread, and that method blocks on the
@synchronized lock inside RCTMarkdownUtils. The stack shows a very deep layout pass, roughly 100
Yoga frames with repeated layoutAbsoluteDescendants recursion, so the measure function is invoked
many times in one pass while the parser lock is held elsewhere. The main thread waits past the two
second watchdog threshold and iOS terminates the app.
Two things worth checking:
- Whether
applyMarkdownFormatting can be made lock free on the measure path, or given a cached
measurement so repeated measures of unchanged text do not re-enter the parser.
- Why the layout tree is this deep. The repeated absolute-position recursion suggests a markdown
input nested inside several absolutely positioned containers, which multiplies measure calls.
Reproduction
Unknown — see the events linked from the Sentry issue. The affected sample includes iPad on iOS 26.6,
so a large composer with long markdown content is a plausible starting point.
Related
Issue Owner
Current Issue Owner: @Krishna2323
Sentry
https://expensify.sentry.io/issues/APP-KDF
Impact (snapshot at filing)
new)AppHang(Fatal App Hang Fully Blocked)-[RCTMarkdownUtils applyMarkdownFormatting:withDefaultTextAttributes:markdownStyle:parserId:]Every affected user in the 14 day window is a new user of this signature, so this is a fresh
regression rather than a long tail.
Stack trace (top frames, main thread)
The event also shows
LiveMarkdownRuntime_queueandLiveMarkdownRuntime(timeout)threads alivewhile the main thread sits in the lock.
Suspected cause
The Yoga measure callback for
MarkdownTextInputDecoratorShadowNodecallsapplyMarkdownFormattingsynchronously on the main thread, and that method blocks on the@synchronizedlock insideRCTMarkdownUtils. The stack shows a very deep layout pass, roughly 100Yoga frames with repeated
layoutAbsoluteDescendantsrecursion, so the measure function is invokedmany times in one pass while the parser lock is held elsewhere. The main thread waits past the two
second watchdog threshold and iOS terminates the app.
Two things worth checking:
applyMarkdownFormattingcan be made lock free on the measure path, or given a cachedmeasurement so repeated measures of unchanged text do not re-enter the parser.
input nested inside several absolutely positioned containers, which multiplies measure calls.
Reproduction
Unknown — see the events linked from the Sentry issue. The affected sample includes iPad on iOS 26.6,
so a large composer with long markdown content is a plausible starting point.
Related
Issue Owner
Current Issue Owner: @Krishna2323