Skip to content

[Due for payment 2026-10-15] [$175] [Sentry: APP-K0G] Fabric addViewAt crashes adding view into non-ViewGroup #102741

Description

@mountiny

Sentry

https://expensify.sentry.io/issues/APP-K0G

Impact (snapshot at filing)

  • Users (total since first seen): 91
  • Events: 91
  • Users (last 14d): not pulled separately
  • First seen: 2026-08-10
  • Last seen: now (ongoing)
  • Platform: Android (HybridApp)
  • App version(s): 9.4.9x through 9.5.0 pre-release builds
  • Affected route(s) (parameterized): n/a — native Fabric mounting, not a JS route
  • Mechanism: UncaughtExceptionHandler (fatal)

Stack trace (top frames, first-party only)

com.facebook.react.fabric.mounting.SurfaceMountingManager.addViewAt (SurfaceMountingManager.kt:330)
com.facebook.react.fabric.mounting.mountitems.IntBufferBatchMountItem.execute
com.facebook.react.fabric.mounting.MountItemDispatcher.executeOrEnqueue
com.facebook.react.fabric.mounting.MountItemDispatcher.dispatchMountItems
com.facebook.react.fabric.FabricUIManager$DispatchUIFrameCallback.doFrameGuarded

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.

Related

  • Sibling Sentry IDs: none identified
  • Prior GH issues: none found
Upwork Automation - Do Not Edit
Issue OwnerCurrent Issue Owner: @eVoloshchak

Activity

  1. self-assigned this
    on Oct 1, 2026
  2. added
    ExternalAdded to denote the issue can be worked on by a contributor
    BugSomething is broken. Auto assigns a BugZero manager.
    on Oct 1, 2026
  3. melvin-bot commented on Oct 1, 2026

    @melvin-bot

    Triggered auto assignment to Contributor-plus team member for initial proposal review - @eVoloshchak (External)

  4. 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
  5. melvin-bot commented on Oct 1, 2026

    @melvin-bot
  6. MelvinBot commented on Oct 1, 2026

    @MelvinBot
    Contributor

    Proposal

    What is the root cause of that problem?

    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.

    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:

    • A delete is delayed during an active touch, and the same tag is recreated before the touch ends.
    • Differ bugs in flatten and unflatten. Upstream fixed these after 0.86.0 in 361bc24.
    • Reanimated layout animations rewrite transactions.

    Upstream already made the matching removeViewAt case a soft exception in 3f553d7. The addViewAt case still crashes.

    What changes do you think we should make in order to solve the problem?

    1. Check Sentry APP-K0G for events on 9.4.93-3 or later. If there are none, close this issue as fixed by PR Fix Android Fabric mount crashes from merged mounting transactions (APP-7AR / APP-H7A) #101057.
    2. 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.
    3. 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:

    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.

    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

  7. mountiny commented on Oct 1, 2026

    @mountiny
    ContributorAuthor

    @eVoloshchak can you review the proposal from melvin please?

  8. eVoloshchak commented on Oct 2, 2026

    @eVoloshchak
    Contributor

    Check Sentry APP-K0G for events on 9.4.93-3 or later.

    Image

    This is present in release 9.4.94-0 , so it wasn't resolved by #101057

    @MelvinBot, implement this

  9. MelvinBot commented on Oct 2, 2026

    @MelvinBot
    Contributor

    🤖 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 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.
  10. mountiny commented on Oct 5, 2026

    @mountiny
    ContributorAuthor

    @eVoloshchak how is this looking?

  11. melvin-bot commented on Oct 5, 2026

    @melvin-bot

    @eVoloshchak Uh oh! This issue is overdue by 2 days. Don't forget to update your issues!

  12. eVoloshchak commented on Oct 6, 2026

    @eVoloshchak
    Contributor

    Taking a look

  13. 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
  14. melvin-bot commented on Oct 8, 2026

    @melvin-bot

    @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]

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

Metadata

Metadata

Labels

BugSomething is broken. Auto assigns a BugZero manager.DailyKSv2ExternalAdded to denote the issue can be worked on by a contributor

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions