You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Due for payment 2026-10-15] [$175] [Sentry: APP-K0G] Fabric addViewAt crashes adding view into non-ViewGroup #102741
Error: IllegalStateException: Unable to add a view into a view that is not a ViewGroup
Suspected cause
Fabric's mounting manager tries to add a view into a parent that has already been removed or replaced, likely a race between an unmount and a queued mount item during a fast re-render.
Reproduction
Unknown — see Sentry events linked from the Sentry issue.
changed the title [-][Sentry: APP-K0G] Fabric addViewAt crashes adding view into non-ViewGroup[/-][+][$175] [Sentry: APP-K0G] Fabric addViewAt crashes adding view into non-ViewGroup[/+]on Oct 1, 2026
Android Fabric crashes in addViewAt when the parent tag has a view state but no usable ViewGroup view. See SurfaceMountingManager.kt:312-331. The check view !is ViewGroup also fails when view is null.
The most likely source is a placeholder view state. updateEventEmitter creates an empty ViewState for any tag that Java no longer has (SurfaceMountingManager.kt:959). When the next batch inserts into that tag, it crashes. Java loses a tag when mount items run in a different order than the shadow tree expects.
If events continue, add an App patch to RN SurfaceMountingManager.addViewAt. When the parent has no ViewGroup view, the patch should log a ReactNoCrashSoftException and skip the insert instead of crashing. This mirrors upstream's removeViewAt change. Put the parent's view class in the message so Sentry shows which component is involved.
In a separate patch, backport upstream differ fix 361bc24 if it applies cleanly to 0.86.0.
Step 2 can leave a single view missing until the next render. That is better than a fatal crash, and it is the same trade-off upstream accepted for removeViewAt.
What alternative solutions did you explore? (Optional)
JS-side fix: I found no App component that passes children to a native view that is not a ViewGroup, such as Image, TextInput, Lottie, or Switch. A JS-side cause would also crash the same user every time. That does not fit 91 events from 91 users.
View recycling or preallocation: I ruled these out. enableViewRecycling is off by default, and preallocation is queued before any batch can run.
Disable mount-item reordering globally: Patch +015 already does this for merged batches. Upstream reports say it does not fix the differ cases.
Investigation details
Confidence: medium. I couldn't connect to Sentry during this run. So I couldn't check two things:
Whether events continue on 9.4.93-3 or later. The issue lists "9.4.9x through 9.5.0", which suggests they might.
Which view class the parent tag belongs to.
How the crash happens:
When the parent's view state is missing, addViewAt only logs a soft exception (L318-L325). It throws only when the state exists but its view is null or not a ViewGroup.
In C++, every Insert also produces an UpdateEventEmitter. If Java has lost a tag, that update creates a placeholder with no view. The next batch's Insert into that parent then fails at L330.
MountItemDispatcher does not swallow IllegalStateException, so the crash is fatal.
What App patch +015 covers:react-native+0.86.0+015+fix-merged-transaction-mount-order.patch mounts merged batches in differ order. The earlier +015 patch could leave several pending transactions for one surface, which was a second source of out-of-order mounts. The new patch fixes that too. It does not cover unmerged transactions, delayed deletes during touches, differ bugs, or transactions rewritten by Reanimated.
Ruled out: A real non-ViewGroup parent is unlikely:
Text nodes are flattened on Android, so they never act as parents.
RN Image throws in JS if it is given children.
No App code passes children to TextInput, Lottie, or Switch.
No library changed its view from ViewGroup to non-ViewGroup in the 0.86 or Expo 57 upgrade.
Sentry data that would settle this:
Version split before and after 9.4.93-3.
Breadcrumbs just before the crash, such as Unable to find viewState for tag.
The screen where it happened. One lead is chat scrolling: the maintainVisibleContentPosition toggle in useReportActionsScroll.ts:207-216 flattens and unflattens many views in one commit.
Next Steps for Contributor+ team: To accept:@MelvinBot implement [this](https://github.com/Expensify/App/issues/102741) to create a draft PR. To refine:@MelvinBot <your feedback> To reject: Explain why you are rejecting Melvin's proposal.
It adds the two patches from steps 2 and 3 of the proposal:
+045: when the parent is not a ViewGroup, addViewAt now logs a ReactNoCrashSoftException with the parent view class and skips the insert, instead of crashing. This matches upstream's removeViewAt change.
+046: backports upstream differ fix 361bc24. It needed one change: 0.86.0's DiffMap has no contains, so the patch uses find(...) != end().
Before you merge, note:
I couldn't run native builds here. CI's Android and iOS builds are the compile check. +046 is C++ code shared by both platforms.
App doesn't forward soft exceptions to Sentry, so the new log goes to logcat only. To confirm the fix, check whether APP-K0G events stop on the release that includes this PR.
changed the title [-][$175] [Sentry: APP-K0G] Fabric addViewAt crashes adding view into non-ViewGroup[/-][+][Due for payment 2026-10-15] [$175] [Sentry: APP-K0G] Fabric addViewAt crashes adding view into non-ViewGroup[/+]on Oct 8, 2026
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.5-2 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:
If no regressions arise, payment will be issued on 2026-10-15. 🎊
The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the Contributor+ Checklist from here into a new comment on this GH and complete it. If you have the K2 extension, you can simply click: [this button]. If no checklist is needed for this issue, you can click: [no checklist button]
Activity
melvin-bot commentedon Oct 1, 2026
Triggered auto assignment to Contributor-plus team member for initial proposal review - @eVoloshchak (
External)[-][Sentry: APP-K0G] Fabric addViewAt crashes adding view into non-ViewGroup[/-][+][$175] [Sentry: APP-K0G] Fabric addViewAt crashes adding view into non-ViewGroup[/+]melvin-bot commentedon Oct 1, 2026
Job added to Upwork: https://www.upwork.com/jobs/~022105599547553887045
MelvinBot commentedon Oct 1, 2026
Proposal
What is the root cause of that problem?
Android Fabric crashes in
addViewAtwhen the parent tag has a view state but no usableViewGroupview. SeeSurfaceMountingManager.kt:312-331. The checkview !is ViewGroupalso fails whenviewis null.The most likely source is a placeholder view state.
updateEventEmittercreates an emptyViewStatefor any tag that Java no longer has (SurfaceMountingManager.kt:959). When the next batch inserts into that tag, it crashes. Java loses a tag when mount items run in a different order than the shadow tree expects.This belongs to the same family as [$250] [Sentry: APP-7AR / APP-H7A] HybridApp Android Fabric mount crash — addViewAt/removeViewAt on clipping views. In RN 0.86, several of those paths only log a soft exception. A broken batch now survives one step longer and fails here. This fits the first-seen date: 2026-08-10 is the day upgrade react native to 0.86.0 merged.
Fix Android Fabric mount crashes from merged mounting transactions (APP-7AR / APP-H7A) shipped in 9.4.93-3. It removed the main source: merged transactions that mounted out of order. Other sources remain:
Upstream already made the matching
removeViewAtcase a soft exception in 3f553d7. TheaddViewAtcase still crashes.What changes do you think we should make in order to solve the problem?
SurfaceMountingManager.addViewAt. When the parent has noViewGroupview, the patch should log aReactNoCrashSoftExceptionand skip the insert instead of crashing. This mirrors upstream'sremoveViewAtchange. Put the parent's view class in the message so Sentry shows which component is involved.Step 2 can leave a single view missing until the next render. That is better than a fatal crash, and it is the same trade-off upstream accepted for
removeViewAt.What alternative solutions did you explore? (Optional)
ViewGroup, such as Image, TextInput, Lottie, or Switch. A JS-side cause would also crash the same user every time. That does not fit 91 events from 91 users.enableViewRecyclingis off by default, and preallocation is queued before any batch can run.Investigation details
Confidence: medium. I couldn't connect to Sentry during this run. So I couldn't check two things:
How the crash happens:
addViewAtonly logs a soft exception (L318-L325). It throws only when the state exists but its view is null or not aViewGroup.UpdateEventEmitter. If Java has lost a tag, that update creates a placeholder with no view. The next batch's Insert into that parent then fails at L330.MountItemDispatcherdoes not swallowIllegalStateException, so the crash is fatal.What App patch +015 covers:
react-native+0.86.0+015+fix-merged-transaction-mount-order.patchmounts merged batches in differ order. The earlier +015 patch could leave several pending transactions for one surface, which was a second source of out-of-order mounts. The new patch fixes that too. It does not cover unmerged transactions, delayed deletes during touches, differ bugs, or transactions rewritten by Reanimated.Ruled out: A real non-
ViewGroupparent is unlikely:Imagethrows in JS if it is given children.ViewGroupto non-ViewGroupin the 0.86 or Expo 57 upgrade.Sentry data that would settle this:
Unable to find viewState for tag.maintainVisibleContentPositiontoggle inuseReportActionsScroll.ts:207-216flattens and unflattens many views in one commit.Related issues
Next Steps for Contributor+ team:
To accept:
@MelvinBot implement [this](https://github.com/Expensify/App/issues/102741)to create a draft PR.To refine:
@MelvinBot <your feedback>To reject: Explain why you are rejecting Melvin's proposal.
view run
mountiny commentedon Oct 1, 2026
@eVoloshchak can you review the proposal from melvin please?
eVoloshchak commentedon Oct 2, 2026
This is present in release 9.4.94-0 , so it wasn't resolved by #101057
@MelvinBot, implement this
MelvinBot commentedon Oct 2, 2026
🤖 Draft PR created: Soft-fail Fabric addViewAt into a non-ViewGroup parent and backport upstream differ fix (APP-K0G)
Please mark it as "Ready for review" when it is ready for review.
It adds the two patches from steps 2 and 3 of the proposal:
+045: when the parent is not aViewGroup,addViewAtnow logs aReactNoCrashSoftExceptionwith the parent view class and skips the insert, instead of crashing. This matches upstream'sremoveViewAtchange.+046: backports upstream differ fix 361bc24. It needed one change: 0.86.0'sDiffMaphas nocontains, so the patch usesfind(...) != end().Before you merge, note:
+046is C++ code shared by both platforms.APP-K0Gevents stop on the release that includes this PR.mountiny commentedon Oct 5, 2026
@eVoloshchak how is this looking?
6 remaining items
[-][$175] [Sentry: APP-K0G] Fabric addViewAt crashes adding view into non-ViewGroup[/-][+][Due for payment 2026-10-15] [$175] [Sentry: APP-K0G] Fabric addViewAt crashes adding view into non-ViewGroup[/+]melvin-bot commentedon Oct 8, 2026
@eVoloshchak
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.5-2 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:
If no regressions arise, payment will be issued on 2026-10-15. 🎊
The following checklist (instructions) will need to be completed before the issue can be closed. Please copy/paste the Contributor+ Checklist from here into a new comment on this GH and complete it. If you have the K2 extension, you can simply click: [this button]. If no checklist is needed for this issue, you can click: [no checklist button]
mountiny commentedon Oct 12, 2026
Monitoring
melvin-bot commentedon Oct 14, 2026
Triggered auto assignment to @mallenexpensify (
Awaiting Payment)melvin-bot commentedon Oct 14, 2026
Payment Summary
Resolving PRs:
Soft-fail Fabric addViewAt into a non-ViewGroup parent and backport upstream differ fix (APP-K0G) #102901
Reviewer: @eVoloshchak owed $175 via NewDot
BugZero Checklist (@mallenexpensify)