Skip to content

Stop crashing on inconsistent clipping bookkeeping in ReactViewGroup.isViewClipped#57365

Closed
rozele wants to merge 1 commit into
react:mainfrom
rozele:export-D109987865
Closed

Stop crashing on inconsistent clipping bookkeeping in ReactViewGroup.isViewClipped#57365
rozele wants to merge 1 commit into
react:mainfrom
rozele:export-D109987865

Conversation

@rozele

@rozele rozele commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Summary:
WARNING: Generated by Autopilot (alpha) - review carefully, verify the underlying claim before accepting.
Agent: React Native Agent | Trajectory: https://www.internalfb.com/intern/devai/devmate/inspector/0ea7c6e3-35be-490c-a17f-66677f75cb75/ | SC job: https://www.internalfb.com/intern/sandcastle/instance/18014401274782879/


What

ReactViewGroup.isViewClipped (the removeClippedSubviews clipping path) crashes with java.lang.IllegalStateException: Check failed. at the hard check(parent === this) in its missing-tag fallback. The crash surfaces in CrashBot via system_vros_crashes with the title frame com.facebook.react.internal.tracing.PerformanceTracer.trace (an incidental Choreographer doFrame wrapper); the real throw site is ReactViewGroup.isViewClippedupdateSubviewClipStatusChildrenLayoutChangeListener.onLayoutChange. Tracked as T277554117 (MID system_vros_crashes/5593272fc690b1c4d240d949710c49e9).

Why

When a child view in allChildren has no view_clipped tag, the method falls back to inferring clip state from the view's parent. The existing code already logs a ReactNoCrashSoftException (RVG_IS_VIEW_CLIPPED) for this inconsistency, signaling that the intent is graceful degradation — but it then hits check(parent === this), which hard-crashes whenever the tag-less child is parented to some other ViewGroup (a reparented/stale-bookkeeping state) rather than to this or to no parent. This is a long-standing invariant (the bookkeeping dates to D66383241 / D66539065, Dec 2024; the check was carried through the Kotlin conversion in D75797215), not a new code regression — it was first observed in crash data on 2026-04-10 and only crossed the top-N FSA detector threshold on 2026-06-28 (%SAD ≈ 0, ~17 occurrences / 7 days).

Fix

Replace the hard check(parent === this) with a non-fatal classification consistent with the surrounding fallback: a view that is transitioning, has no parent, or is parented elsewhere is no longer a live child of this, so it is reported as clipped (true); only a view still parented to this and not transitioning is reported as not clipped (false). This preserves the existing behavior for every previously non-crashing path (parent == null / transitioningtrue; parent === thisfalse) and converts only the previously-crashing reparented case into the same "treat as removed" outcome the soft exception already anticipates.

Differential Revision: D109987865

…isViewClipped

Summary:
WARNING: Generated by Autopilot (alpha) - review carefully, verify the underlying claim before accepting.
Agent: React Native Agent | Trajectory: https://www.internalfb.com/intern/devai/devmate/inspector/0ea7c6e3-35be-490c-a17f-66677f75cb75/ | SC job: https://www.internalfb.com/intern/sandcastle/instance/18014401274782879/

---

## What

`ReactViewGroup.isViewClipped` (the `removeClippedSubviews` clipping path) crashes with `java.lang.IllegalStateException: Check failed.` at the hard `check(parent === this)` in its missing-tag fallback. The crash surfaces in CrashBot via `system_vros_crashes` with the title frame `com.facebook.react.internal.tracing.PerformanceTracer.trace` (an incidental Choreographer `doFrame` wrapper); the real throw site is `ReactViewGroup.isViewClipped` ← `updateSubviewClipStatus` ← `ChildrenLayoutChangeListener.onLayoutChange`. Tracked as T277554117 (MID `system_vros_crashes/5593272fc690b1c4d240d949710c49e9`).

## Why

When a child view in `allChildren` has no `view_clipped` tag, the method falls back to inferring clip state from the view's parent. The existing code already logs a `ReactNoCrashSoftException` (`RVG_IS_VIEW_CLIPPED`) for this inconsistency, signaling that the intent is graceful degradation — but it then hits `check(parent === this)`, which hard-crashes whenever the tag-less child is parented to some *other* `ViewGroup` (a reparented/stale-bookkeeping state) rather than to `this` or to no parent. This is a long-standing invariant (the bookkeeping dates to D66383241 / D66539065, Dec 2024; the `check` was carried through the Kotlin conversion in D75797215), not a new code regression — it was first observed in crash data on 2026-04-10 and only crossed the top-N FSA detector threshold on 2026-06-28 (`%SAD ≈ 0`, ~17 occurrences / 7 days).

## Fix

Replace the hard `check(parent === this)` with a non-fatal classification consistent with the surrounding fallback: a view that is transitioning, has no parent, or is parented elsewhere is no longer a live child of `this`, so it is reported as clipped (`true`); only a view still parented to `this` and not transitioning is reported as not clipped (`false`). This preserves the existing behavior for every previously non-crashing path (`parent == null` / `transitioning` → `true`; `parent === this` → `false`) and converts only the previously-crashing reparented case into the same "treat as removed" outcome the soft exception already anticipates.

Differential Revision: D109987865
@meta-codesync

meta-codesync Bot commented Jun 29, 2026

Copy link
Copy Markdown

@rozele has exported this pull request. If you are a Meta employee, you can view the originating Diff in D109987865.

@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 Jun 29, 2026
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. meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant