Skip to content

fix(recycling): disable removeClippedSubviews to prevent Android crash#2202

Merged
naqvitalha merged 4 commits into
mainfrom
fix/issue-1914-disable-remove-clipped-subviews
Mar 23, 2026
Merged

fix(recycling): disable removeClippedSubviews to prevent Android crash#2202
naqvitalha merged 4 commits into
mainfrom
fix/issue-1914-disable-remove-clipped-subviews

Conversation

@shopify-github-actions-access
Copy link
Copy Markdown
Contributor

Description

On Android with Fabric (New Architecture), the native removeClippedSubviews optimization can detach views that FlashList has buffered off-screen via absolute positioning. When FlashList then recycles those views back on-screen, Fabric cannot find their view state, causing the "Unable to find viewState for tag" crash.

This fix explicitly disables removeClippedSubviews on the ScrollView and the item container view. FlashList v2 manages its own view recycling through key reuse and absolute positioning, so the native clipping optimization is both unnecessary and harmful.

Fixes #1914

Reviewers' hat-rack 🎩

  • Verify the prop placement: removeClippedSubviews={false} is placed after {...overrideProps} on the ScrollView to ensure it cannot be accidentally re-enabled by user props.
  • The same prop is set on the ViewHolderCollection container (the parent of all absolutely-positioned items) for defense in depth.
  • Consider whether this should also be documented as a known incompatibility with removeClippedSubviews.

Test plan

  • Unit tests pass (yarn test)
  • Type check passes (yarn type-check)
  • Lint passes (yarn lint)
  • Verified on Android device/emulator (crash no longer occurs when scrolling)
  • No regressions on iOS simulator

On Android with Fabric (New Architecture), the native removeClippedSubviews
optimization can detach views that FlashList has buffered off-screen via
absolute positioning. When FlashList recycles those views back on-screen,
Fabric cannot find their view state, causing the Unable to find viewState
for tag crash.

FlashList v2 manages its own view recycling through key reuse and absolute
positioning, so the native clipping optimization is both unnecessary and
harmful. This explicitly disables removeClippedSubviews on the ScrollView
and the item container to prevent the conflict.

Fixes #1914
@naqvitalha
Copy link
Copy Markdown
Collaborator

@agent Let's place the removeCLipped prop above override so that people can disable or enable if they want. Update the PR

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 23, 2026

Claude finished @naqvitalha's task in 51s —— View job


Updating removeClippedSubviews prop placement

  • Read current code and understand the change needed
  • Move removeClippedSubviews={false} before {...overrideProps} in RecyclerView
  • Commit and push

Moved removeClippedSubviews={false} above {...overrideProps} on the ScrollView so users can override it via overrideProps if they choose to.
| Branch

Move removeClippedSubviews={false} above {...overrideProps} so users can
override the default if needed.

Fixes #1914

Co-authored-by: Talha Naqvi <naqvitalha@users.noreply.github.com>
claude-code-action injects Co-authored-by trailers for the trigger user
into commits. This is unwanted — agent commits should have no co-author
attribution. Override via system prompt in all commit-capable workflows.
…rCollection

Only needed on the outer ScrollView, not the inner container.
@naqvitalha naqvitalha merged commit 4fa1ccd into main Mar 23, 2026
11 checks passed
@naqvitalha naqvitalha deleted the fix/issue-1914-disable-remove-clipped-subviews branch March 23, 2026 23:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unable to find viewState for tag 10254. Surface stopped: false

1 participant