Skip to content

Fix TalkBack crash in ReactScrollViewAccessibilityDelegate when a list child has no accessibilityCollectionItem - #58660

Open
iray-tno wants to merge 1 commit into
react:mainfrom
iray-tno:claude/react-native-changes-8rvmxi
Open

iray-tno wants to merge 1 commit into
react:mainfrom
iray-tno:claude/react-native-changes-8rvmxi

Conversation

@iray-tno

Copy link
Copy Markdown

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:

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

Test Plan:

  • One-token change (asas?); 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

…accessibilityCollectionItem

onInitializeAccessibilityEventInternal read a child's
accessibility_collection_item tag with a non-null `as` cast into a
nullable variable, even though the code right below handles the null
case (checking one nested child, for FlatList without getItemLayout).

When a ScrollView has accessibilityCollection set and any direct child
of its content view has no accessibilityCollectionItem tag, e.g. a
FlatList ListHeaderComponent or ListFooterComponent, the cast throws
NullPointerException. With TalkBack on this crashes the app, for
example when Fabric removes the accessibility-focused view on
navigation and the resulting event reaches the delegate.

Use `as?` so the existing null handling runs as intended, matching the
other tag reads in this file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Sep 24, 2026
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Sep 24, 2026
@meta-codesync

meta-codesync Bot commented Sep 24, 2026

Copy link
Copy Markdown

@cortinico has imported this pull request. If you are a Meta employee, you can view this in D121556760.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants