Description
iOS production EXC_BAD_ACCESS (KERN_INVALID_ADDRESS at 0x18) crash on react-native-reanimated@4.3.1 + react-native-worklets@0.8.3 + Fabric. The crash signature is structurally identical to #9293 / #9303 (a mount-time deref of a stale view during a reanimated commit) but is triggered through a different upstream path: react-native-screens' per-frame notifyTransitionProgress event during a native-stack screen pop, not the rAF / AnimationFrameBatchinator::flush() path that #9293 OP described.
The registry-locking fix in 4.3.1 (PRs #9308, #9323; release tagged 2026-05-07) resolved one variant we were hitting (chat-list-scroll EXC_BAD_ACCESS in AnimatedPropsRegistry::update). The screen-pop variant in this report is still happening after upgrading to 4.3.1, in line with @florian-deroo's and @LeCiel's post-fix reports in #9293.
Crash flow
Main-thread stack at the moment of segfault (real production crash from a TestFlight 1.0.9 build cut after the 4.3.1 bump):
0 [Redacted] RCTPerformMountInstructions (RCTMountingManager.mm)
10 [Redacted] -[RCTMountingManager performTransaction:] (:258)
11 [Redacted] -[RCTMountingManager initiateTransaction:] (:246)
12 [Redacted] -[RCTSurfacePresenter schedulerShouldRenderTransactions:] (:307)
14 [Redacted] facebook::react::Scheduler::uiManagerDidFinishTransaction (Scheduler.cpp:279)
15 [Redacted] facebook::react::UIManager::shadowTreeDidFinishTransaction (UIManager.cpp:637)
16 [Redacted] facebook::react::ShadowTree::notifyDelegatesOfUpdates (ShadowTree.cpp:426)
17 [Redacted] facebook::react::ShadowTreeRegistry::visit (ShadowTreeRegistry.cpp:50)
20 [Redacted] reanimated::ReanimatedModuleProxy::performOperations() (ReanimatedModuleProxy.cpp:673)
21 [Redacted] reanimated::ReanimatedModuleProxy::handleRawEvent (ReanimatedModuleProxy.cpp:619)
22 [Redacted] -[ReanimatedModule attachReactEventListener:]::block-literal::$_0::operator()
30 [Redacted] facebook::react::EventListenerContainer::willDispatchEvent
31 [Redacted] facebook::react::EventDispatcher::dispatchEvent
32 [Redacted] facebook::react::EventEmitter::dispatchEvent
34 [Redacted] facebook::react::RNSScreenEventEmitter::onTransitionProgress (EventEmitters.cpp:315)
35 [Redacted] -[RNSScreenView notifyTransitionProgress:closing:goingForward:] (RNSScreen.mm:790)
36 [Redacted] -[RNSScreen notifyTransitionProgress:closing:goingForward:] (RNSScreen.mm:1983)
37 QuartzCore CA::Display::DisplayLinkItem::dispatch_
38 QuartzCore CA::Display::DisplayLink::dispatch_items
39 QuartzCore CA::Display::DisplayLink::dispatch_deferred_display_links
- Exception:
EXC_BAD_ACCESS (SIGSEGV) / KERN_INVALID_ADDRESS at 0x0000000000000018
- The faulting load is a null+offset deref — classic stale-pointer-to-deallocated-object signature inside the mounting layer.
What we believe is happening
- The user pops a native-stack screen (
react-native-screens@4.25.0, no Reanimated*Stack wrapping — vanilla @react-navigation/native-stack).
- UIKit's
CADisplayLink ticks during the transition.
RNSScreen::notifyTransitionProgress fires the Fabric onTransitionProgress event every frame (see RNSScreen.mm:1797 → :635; the call is unconditional, no listener gating).
- The event flows through
EventDispatcher::dispatchEvent → EventListenerContainer::willDispatchEvent → reanimated's listener → ReanimatedModuleProxy::handleRawEvent.
- Inside
handleRawEvent, control reaches performOperations() at line 619 — i.e. either (a) StaticFeatureFlags::ENABLE_SHARED_ELEMENT_TRANSITIONS is disabled at build time so the early-return branch is removed, or (b) a JS handler is registered for onTransitionProgress on this view tag (e.g. via useReanimatedTransitionProgress) and the function fell through past isAnyHandlerWaitingForEvent.
performOperations() flushes layoutAnimationFlushRequests_ at line 673 and visits each surface's shadow tree.
ShadowTree::notifyDelegatesOfUpdates commits a mount transaction. RCTPerformMountInstructions applies a queued mutation against a RCTViewComponentView whose backing UIView is mid-teardown by the screen pop — null deref.
The mutation being flushed is queued by in-flight withSpring/withTiming animations that have not been cancelled before the unmount transaction runs. We confirmed this empirically: the only application-side mitigation that has stopped the crash so far in our internal testing is draining all SharedValues tied to animated styles in the popping subtree before the transition starts (cancelling animations + gating event-driven worklets via a closing flag on navigation.addListener('beforeRemove')).
Why we think this is a follow-up to #9293, not the same bug
Happy to be told this is the same bug and to comment on #9293 instead — flagging as a separate issue to make the screen-pop path visible.
Steps to reproduce
We do not have a deterministic standalone repro and we cannot reproduce on a developer machine (debug builds, internal staging, simulators, or the same physical device with the same account all fail to trigger). The crash is observed in production telemetry across multiple unrelated users; some users reproduce it 100% of the time on every screen, others never. We have not isolated the personal axis.
Snack or a link to a repository
N/A
Reanimated version
4.3.1
Worklets version
0.8.3
React Native version
0.83.9
Platforms
iOS
JavaScript runtime
Hermes
Workflow
Expo Dev Client
Architecture
New Architecture (Fabric renderer)
Reanimated feature flags
No
React Native release level
Stable
Build type
Release app & production bundle
Device
Real device
Host machine
macOS
Device model
iPhone17,1
Acknowledgements
Yes
Description
iOS production
EXC_BAD_ACCESS (KERN_INVALID_ADDRESS at 0x18)crash onreact-native-reanimated@4.3.1+react-native-worklets@0.8.3+ Fabric. The crash signature is structurally identical to #9293 / #9303 (a mount-time deref of a stale view during a reanimated commit) but is triggered through a different upstream path:react-native-screens' per-framenotifyTransitionProgressevent during a native-stack screen pop, not the rAF /AnimationFrameBatchinator::flush()path that #9293 OP described.The registry-locking fix in 4.3.1 (PRs #9308, #9323; release tagged 2026-05-07) resolved one variant we were hitting (chat-list-scroll EXC_BAD_ACCESS in
AnimatedPropsRegistry::update). The screen-pop variant in this report is still happening after upgrading to 4.3.1, in line with @florian-deroo's and @LeCiel's post-fix reports in #9293.Crash flow
Main-thread stack at the moment of segfault (real production crash from a TestFlight 1.0.9 build cut after the 4.3.1 bump):
EXC_BAD_ACCESS (SIGSEGV)/KERN_INVALID_ADDRESS at 0x0000000000000018What we believe is happening
react-native-screens@4.25.0, noReanimated*Stackwrapping — vanilla@react-navigation/native-stack).CADisplayLinkticks during the transition.RNSScreen::notifyTransitionProgressfires the FabriconTransitionProgressevent every frame (seeRNSScreen.mm:1797 → :635; the call is unconditional, no listener gating).EventDispatcher::dispatchEvent→EventListenerContainer::willDispatchEvent→ reanimated's listener →ReanimatedModuleProxy::handleRawEvent.handleRawEvent, control reachesperformOperations()at line 619 — i.e. either (a)StaticFeatureFlags::ENABLE_SHARED_ELEMENT_TRANSITIONSis disabled at build time so the early-return branch is removed, or (b) a JS handler is registered foronTransitionProgresson this view tag (e.g. viauseReanimatedTransitionProgress) and the function fell through pastisAnyHandlerWaitingForEvent.performOperations()flusheslayoutAnimationFlushRequests_at line 673 and visits each surface's shadow tree.ShadowTree::notifyDelegatesOfUpdatescommits a mount transaction.RCTPerformMountInstructionsapplies a queued mutation against aRCTViewComponentViewwhose backingUIViewis mid-teardown by the screen pop — null deref.The mutation being flushed is queued by in-flight
withSpring/withTiminganimations that have not been cancelled before the unmount transaction runs. We confirmed this empirically: the only application-side mitigation that has stopped the crash so far in our internal testing is draining allSharedValues tied to animated styles in the popping subtree before the transition starts (cancelling animations + gating event-driven worklets via aclosingflag onnavigation.addListener('beforeRemove')).Why we think this is a follow-up to #9293, not the same bug
AnimationFrameBatchinator::flush()/WorkletRuntime::runSync(the rAF path). Ours goes throughRNSScreenEventEmitter::onTransitionProgress→EventDispatcher::dispatchEvent(the event-dispatch path). The crash site is the same (performOperations→ mount → null deref) but the call site ofperformOperationsis different.performOperations()and unmounting a focused view (removeFromSuperview -> resignFirstResponder)" — consistent with the screen-pop teardown window described here.Happy to be told this is the same bug and to comment on #9293 instead — flagging as a separate issue to make the screen-pop path visible.
Steps to reproduce
We do not have a deterministic standalone repro and we cannot reproduce on a developer machine (debug builds, internal staging, simulators, or the same physical device with the same account all fail to trigger). The crash is observed in production telemetry across multiple unrelated users; some users reproduce it 100% of the time on every screen, others never. We have not isolated the personal axis.
Snack or a link to a repository
N/A
Reanimated version
4.3.1
Worklets version
0.8.3
React Native version
0.83.9
Platforms
iOS
JavaScript runtime
Hermes
Workflow
Expo Dev Client
Architecture
New Architecture (Fabric renderer)
Reanimated feature flags
No
React Native release level
Stable
Build type
Release app & production bundle
Device
Real device
Host machine
macOS
Device model
iPhone17,1
Acknowledgements
Yes