Skip to content

Commit 2915fe0

Browse files
iray-tnometa-codesync[bot]
authored andcommitted
Fix TalkBack crash in ReactScrollViewAccessibilityDelegate when a list child has no accessibilityCollectionItem (#58660)
Summary: With TalkBack on, a `ScrollView` that has `accessibilityCollection` set crashes the app as soon as any direct child of its content view lacks `accessibilityCollectionItem` — e.g. a FlatList `ListHeaderComponent` or `ListFooterComponent`. It reproduces on a common path: a screen reader user navigating away from a list screen. In release builds there is no red box; the process just dies. ``` java.lang.NullPointerException: null cannot be cast to non-null type com.facebook.react.bridge.ReadableMap at ReactScrollViewAccessibilityDelegate.onInitializeAccessibilityEventInternal(ReactScrollViewAccessibilityDelegate.kt:74) ... at android.view.View.clearAccessibilityFocus(View.java:15215) at android.view.ViewGroup.removeViewInternal(ViewGroup.java:5611) at com.facebook.react.fabric.mounting.SurfaceMountingManager.removeViewAt(SurfaceMountingManager.kt:493) ``` The cause is a non-null cast on a value the code expects to be null: ```kotlin var accessibilityCollectionItem: ReadableMap? = nextChild.getTag(R.id.accessibility_collection_item) as ReadableMap // throws on null ... // If this child's accessibilityCollectionItem is null, we'll check one more nested child. if (nextChild.childCount > 0 && accessibilityCollectionItem == null) { ``` The variable is declared nullable and the null branch right below it was written for exactly this case, but the `as` cast throws before that branch can run. This PR changes it to `as?`, matching the other tag reads in the same file. No behavior change for children that do carry the tag. It has gone unnoticed because no React Native component sets `accessibilityCollection` itself (it was added in 105a239 for #30977), so the early return at the top of the method skips this code for core lists. Any library that sets it to announce a windowed list's real length hits the crash immediately. Observed on 0.87.1 (API 36, new architecture, Hermes); details in iray-tno/hozo#512. ## Changelog: [ANDROID] [FIXED] - Fix crash in ScrollView accessibility delegate when `accessibilityCollection` is set and a child (e.g. a list header or footer) has no `accessibilityCollectionItem` Pull Request resolved: #58660 Test Plan: - One-token change (`as` → `as?`); the assigned variable is already `ReadableMap?` and all later uses are null-checked, so types are unchanged. - Not built or tested locally: the environment had no Android SDK. Relying on CI for the Android build. - Repro (before this change): Android + TalkBack, a `FlatList` with `ListHeaderComponent`, `accessibilityCollection` on the list and `accessibilityCollectionItem` on cells only; put accessibility focus inside the list and unmount the screen → crash above. Expected after: no crash. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed By: Abbondanzo Differential Revision: D121556760 Pulled By: cortinico fbshipit-source-id: ccbfe470dc53adec3deac3458b83ae2bc08a48cb
1 parent 9fae71c commit 2915fe0

1 file changed

Lines changed: 1 addition & 1 deletion

File tree

‎packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewAccessibilityDelegate.kt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ internal class ReactScrollViewAccessibilityDelegate : AccessibilityDelegateCompa
7171
return
7272
}
7373
var accessibilityCollectionItem: ReadableMap? =
74-
nextChild.getTag(R.id.accessibility_collection_item) as ReadableMap
74+
nextChild.getTag(R.id.accessibility_collection_item) as? ReadableMap
7575

7676
if (nextChild !is ViewGroup) {
7777
return

0 commit comments

Comments
 (0)