Environment
- Detox:
20.51.3 (behavior confirmed unchanged in the 20.51.4 AAR bytecode via javap — the constant pool still hardcodes the literal "mMountItemDispatcher" for the Reflect.field() call)
- React Native:
0.85.3, newArchEnabled=true, hermesEnabled=true, bridgeless
- Platform: Android emulator, debug build
Stack trace
java.util.concurrent.ExecutionException: org.joor.ReflectException:
org.joor.ReflectException: java.lang.NoSuchFieldException: mMountItemDispatcher
at com.wix.detox.reactnative.idlingresources.uimodule.fabric
.FabricUIManagerIdlingResources.getMountItemDispatcher
(FabricUIManagerIdlingResources.kt:103)
Occurs on the first .tap() issued after a screen has fully attached via Fabric.
What I've verified (static analysis of the installed react-native@0.85.3 source that compiles into the RN AAR)
ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java:179 still declares private final MountItemDispatcher mMountItemDispatcher;. The field name has NOT been renamed in RN 0.85.
- Under
newArchEnabled=true + bridgeless, BridgelessReactContext.kt:73 returns reactHost.uiManager, which is ReactInstance.kt:106-107's val fabricUIManager: FabricUIManager — the direct concrete class. No proxy or synthetic wrapper.
- Debug builds don't apply R8 (
minifyEnabled enableProguardInReleaseBuilds — false for debug), so field-name obfuscation is ruled out.
Yet Reflect.on(fabricUIManager).field("mMountItemDispatcher") at FabricUIManagerIdlingResources.kt:103 fails with NoSuchFieldException.
Hypotheses (not yet pinned)
FabricUIManagerBinding.register() (via FabricUIManagerProviderImpl.kt:64) completes lazily through JSI. The idling-resource frame callback may reflect on the JVM instance during a window where the internal state isn't yet what the string lookup expects.
- jOOR's
.field() may fail on hierarchy traversal under some AGP/Kotlin version combinations, though the field is directly declared on the concrete class, not inherited.
- RN may have shipped an intermediate 0.85.x patch that briefly changed the field name or added a proxy layer that isn't visible in the current 0.85.3 source.
Proposed fix
Regardless of root cause, the reflection at FabricUIManagerIdlingResources.getMountItemDispatcher() currently hard-codes the field name string. Mirroring the existing version-aware conditional at line 92 for mountItems / mMountItems, and/or catching NoSuchFieldException + falling back to reporting idle, would prevent this class of crash across future RN patch releases.
Environment
20.51.3(behavior confirmed unchanged in the20.51.4AAR bytecode viajavap— the constant pool still hardcodes the literal"mMountItemDispatcher"for theReflect.field()call)0.85.3,newArchEnabled=true,hermesEnabled=true, bridgelessStack trace
Occurs on the first
.tap()issued after a screen has fully attached via Fabric.What I've verified (static analysis of the installed
react-native@0.85.3source that compiles into the RN AAR)ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java:179still declaresprivate final MountItemDispatcher mMountItemDispatcher;. The field name has NOT been renamed in RN 0.85.newArchEnabled=true+ bridgeless,BridgelessReactContext.kt:73returnsreactHost.uiManager, which isReactInstance.kt:106-107'sval fabricUIManager: FabricUIManager— the direct concrete class. No proxy or synthetic wrapper.minifyEnabled enableProguardInReleaseBuilds— false for debug), so field-name obfuscation is ruled out.Yet
Reflect.on(fabricUIManager).field("mMountItemDispatcher")atFabricUIManagerIdlingResources.kt:103fails withNoSuchFieldException.Hypotheses (not yet pinned)
FabricUIManagerBinding.register()(viaFabricUIManagerProviderImpl.kt:64) completes lazily through JSI. The idling-resource frame callback may reflect on the JVM instance during a window where the internal state isn't yet what the string lookup expects..field()may fail on hierarchy traversal under some AGP/Kotlin version combinations, though the field is directly declared on the concrete class, not inherited.Proposed fix
Regardless of root cause, the reflection at
FabricUIManagerIdlingResources.getMountItemDispatcher()currently hard-codes the field name string. Mirroring the existing version-aware conditional at line 92 formountItems/mMountItems, and/or catchingNoSuchFieldException+ falling back to reporting idle, would prevent this class of crash across future RN patch releases.