Skip to content

fix(android): getChildDrawingOrder crash in react-native-screens ScreenStack#7368

Open
OtavioStasiak wants to merge 4 commits into
developfrom
fix.android-crash-invalid-index-react-native-screens
Open

fix(android): getChildDrawingOrder crash in react-native-screens ScreenStack#7368
OtavioStasiak wants to merge 4 commits into
developfrom
fix.android-crash-invalid-index-react-native-screens

Conversation

@OtavioStasiak
Copy link
Copy Markdown
Contributor

@OtavioStasiak OtavioStasiak commented Jun 1, 2026

Proposed changes

Fixes an intermittent Android crash during view draw/navigation:

  java.lang.IndexOutOfBoundsException: getChildDrawingOrder() returned invalid index 4 (child count
  is 4)
    at android.view.ViewGroup.getAndVerifyPreorderedIndex
    at android.view.ViewGroup.dispatchDraw
    at com.facebook.react.views.view.ReactViewGroup.drawChild
    at com.swmansion.rnscreens.ScreenStack.performDraw
    at com.swmansion.rnscreens.ScreenStack.dispatchDraw
    at androidx.coordinatorlayout.widget.CoordinatorLayout.drawChild
    at android.view.Choreographer.doFrame

The crash fires when Android validates child draw order during a frame draw
(getChildDrawingOrder()) and react-native-screens' ScreenStack returns a stale/out-of-range index.
It surfaces under fast native-stack transitions, especially around screens that use the native
Android RefreshControl.

Root cause

A known upstream race in react-native-screens ScreenStack draw ordering during native-stack
transitions on the new architecture. Reproduces most often when a native RefreshControl
(pull-to-refresh) is mounted on the screen being transitioned away from.

In our app the native RefreshControl is used on the highest-traffic navigation paths:

  • app/views/RoomsListView/index.tsx (main inbox — primary suspect)
  • app/views/ReadReceiptView/index.tsx

Combined with our deeply nested native stacks (MasterDetailStack, InsideStack, modals), this
matches the multiple ScreenStack.performDraw frames seen in the tombstone.

Upstream references:

The fix landed upstream in react-native-screens >= 4.17.x.

Changes

Upgrade react-native-screens from ~4.16.0 to ~4.17.1, the first release in our supported range
(Expo 54 / RN 0.81) that includes the upstream draw-order fix.

  • package.json — bump dependency ~4.16.0 → ~4.17.1
  • pnpm-lock.yaml — regenerated
  • ios/Podfile.lock — RNScreens pod 4.16.0 → 4.17.1

No application code changes were required — replacing the native RefreshControl with a JS/custom
implementation was held as a fallback and proved unnecessary.

Issue(s)

https://rocketchat.atlassian.net/browse/NATIVE-1191

How to test or reproduce

Stress loop (repeat ~30–50× on an Android device/emulator, release arm64):

  • Open Rooms list → pull-to-refresh → immediately navigate into a room → press back quickly
  • Repeat with the refresh spinner still visible
  • Room → Read receipts → pull refresh → back rapidly
  • Push into a FlatList screen → OS back within ~300ms, repeat several times
  • Compare phone vs tablet master-detail layout
  • Confirm no getChildDrawingOrder fatal in logcat:

adb logcat -d | rg "getChildDrawingOrder|ScreenStack.performDraw|FATAL EXCEPTION"

Screenshots

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • Improvement (non-breaking change which improves a current function)
  • New feature (non-breaking change which adds functionality)
  • Documentation update (if none of the other choices apply)

Checklist

  • I have read the CONTRIBUTING doc
  • I have signed the CLA
  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works (if applicable)
  • I have added necessary documentation (if applicable)
  • Any dependent changes have been merged and published in downstream modules

Further comments

Summary by CodeRabbit

  • Chores
    • Updated the react-native-screens library dependency from version 4.16.0 to 4.17.1. This routine maintenance update enhances native screen navigation performance across the application, improves overall platform stability and reliability on both iOS and Android devices, and incorporates recent bug fixes and compatibility enhancements from the upstream library.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 194bd8b2-20cd-4e9d-bfd6-f6d3fd5b7c4c

📥 Commits

Reviewing files that changed from the base of the PR and between f9168c8 and e9c2aff.

⛔ Files ignored due to path filters (2)
  • ios/Podfile.lock is excluded by !**/*.lock
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (1)
  • package.json
📜 Recent review details
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2026-02-05T13:55:00.974Z
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6930
File: package.json:101-101
Timestamp: 2026-02-05T13:55:00.974Z
Learning: In this repository, the dependency on react-native-image-crop-picker should reference the RocketChat fork (RocketChat/react-native-image-crop-picker) with explicit commit pins, not the upstream ivpusic/react-native-image-crop-picker. Update package.json dependencies (and any lockfile) to point to the fork URL and a specific commit, ensuring edge-to-edge Android fixes are included. This pattern should apply to all package.json files in the repo that declare this dependency.

Applied to files:

  • package.json
📚 Learning: 2026-05-07T17:47:14.516Z
Learnt from: diegolmello
Repo: RocketChat/Rocket.Chat.ReactNative PR: 7303
File: package.json:5-5
Timestamp: 2026-05-07T17:47:14.516Z
Learning: When reviewing pnpm `packageManager` version pins in any `package.json` (e.g., `"packageManager": "pnpm@<version>"`), don’t rely solely on web-search results to determine whether a version exists. For very recently published versions, cross-check the target version against the official pnpm release page (https://github.com/pnpm/pnpm/releases) and the npm registry page for pnpm (https://www.npmjs.com/package/pnpm) before flagging the pinned version as non-existent.

Applied to files:

  • package.json
🔇 Additional comments (2)
package.json (2)

120-120: LGTM!


120-120: ⚡ Quick win

Confirm react-native-screens bump to ~4.17.1 is safe; remaining check is react-navigation peer compatibility

  • react-native-screens@4.17.1 exists on npm, and the security-advisory lookup for the NPM package returned no vulnerabilities.
  • The Android getChildDrawingOrder IndexOutOfBoundsException fix is associated with react-native-screens PR #2964, with reports indicating >= 4.17.1 resolves the crash.
  • Still confirm the repo’s current @react-navigation/* versions (e.g., @react-navigation/native-stack@^7.3.23) accept react-native-screens@4.17.x in their peerDependencies to avoid peer-dependency conflicts.

Walkthrough

The react-native-screens dependency in package.json is updated from version ~4.16.0 to ~4.17.1. This is a minor version bump within the compatible tilde range.

Changes

Dependency Update

Layer / File(s) Summary
Dependency version bump
package.json
react-native-screens dependency is bumped to ~4.17.1 from ~4.16.0.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

Suggested labels

type: bug

Suggested reviewers

  • diegolmello
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: fixing an Android crash in react-native-screens ScreenStack by bumping the dependency version to include the upstream fix.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • NATIVE-1191: Request failed with status code 401

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@OtavioStasiak OtavioStasiak temporarily deployed to approve_e2e_testing June 2, 2026 19:12 — with GitHub Actions Inactive
@OtavioStasiak OtavioStasiak marked this pull request as ready for review June 2, 2026 19:58
@OtavioStasiak
Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 2, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant