microsoft / microsoft/microsoft-ui-xaml

ItemsView crashes with E_INVALIDARG when a pending bring-into-view target is collapsed

Open
#11,865 2 comments 0 reactions 1 assignee Claimed by @gpaskaleva-msft View on GitHub
area-ItemsView area-Scrolling bug
Dominant language
C++
Stars
8.4k
Forks
942
Avg merge
2d 7h
Merged PRs (30d)
105

Description

### Describe the bug

`ItemsView.StartBringItemIntoView` retains its target in `m_bringIntoViewElement`. If that item subsequently becomes collapsed, a later layout pass can cause `ItemsView` to submit that now-invalid element as the scroll anchor. `ScrollingAnchorRequestedEventArgs::AnchorElement` throws `E_INVALIDARG`, and the application terminates with a stowed exception.

The minimal reproduction below uses only WinUI controls and two items. It does **not** require Reactor, OpenClaw, a gateway, Markdown rendering, or a large data set. An explicit `UpdateLayout()` call is **not required**.

### Why is this important?

I encountered this crash while investigating session/history navigation in OpenClaw: [openclaw/openclaw-windows-node#1167](https://github.com/openclaw/openclaw-windows-node/issues/1167).

Switching back and forth between large chat sessions can crash during automatic bottom-positioning. A bring target may become invalid as the displayed rows change. I manually confirmed that the simple reproduction reaches the same failing native code path as the OpenClaw crash.

This report specifically concerns the confirmed invalid-anchor **crash**. The linked OpenClaw issue also discusses a CPU-bound hang; this report does not establish that the hang has the same cause.

### Steps to reproduce the bug

1. Create a blank C# WinUI 3 app using `Microsoft.WindowsAppSDK` **2.4.0**. The example below assumes the project namespace is `ReproApp`.
2. Replace `MainWindow.xaml` and `MainWindow.xaml.cs` with the following.
3. Run the app and click **Reproduce crash** once.
4. The next layout pass throws. For synchronous debugger stepping, optionally uncomment the `UpdateLayout()` call.

**MainWindow.xaml**

```xml












```

**MainWindow.xaml.cs**

```csharp
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;

namespace ReproApp;

public sealed partial class MainWindow : Window
{
private readonly ItemContainer _target = new()
{
Height = 100,
Child = new TextBlock { Text = "Target" },
};

public MainWindow()
{
InitializeComponent();
Items.ItemsSource = new[]
{
new ItemContainer { Height = 2000, Child = new TextBlock { Text = "First item" } },
_target,
};
}

private void OnReproduce(object sender, RoutedEventArgs args)
{
Items.StartBringItemIntoView(1, new BringIntoViewOptions { AnimationDesired = false });
_target.Visibility = Visibility.Collapsed;

// Optional: makes the failure synchronous for debugger stepping.
// Items.UpdateLayout();
}
}
```

### Actual behavior

- `E_INVALIDARG` / `0x80070057`: "The parameter is incorrect."
- With explicit `UpdateLayout()`, the exception is surfaced as `System.ArgumentException` at that call.
- Without explicit `UpdateLayout()`, the failure occurs during the normal deferred layout pass.
- The process terminates with native stowed exception `0xC000027B`.

### Expected behavior

Collapsing an item during a pending bring-into-view operation should cancel or invalidate the pending target, or allow selection of another eligible anchor. It should not cause an unhandled exception during layout.

### NuGet package version

- `Microsoft.WindowsAppSDK`: **2.4.0**
- Loaded native `Microsoft.UI.Xaml.dll`: **3.2.3.2608**
- Native binary source revision: `aa188bfdf74608810e8e57228db6dd137f4e74e4`
- `Microsoft.Windows.SDK.BuildTools`: **10.0.28000.2705**
- Repro target framework: `net10.0-windows10.0.26100.0`
- .NET runtime: **10.0.12**

### Windows version

Windows 11 Enterprise (25H2), build **26200**, ARM64.

### Additional context

Note that the reproducer is a narrowed-down simplified version that triggers the same callstack, but the actual failure-case in OpenClaw to get to this point is more complicated - the collapsing of the view is just a more reliable/simple way to trigger the behavior.

Matching native PDBs and stowed-exception stacks identify the following relevant frames (WinRT forwarding frames omitted):

```text
ScrollingAnchorRequestedEventArgs::AnchorElement
ScrollingAnchorRequestedEventArgs.cpp:43, throws E_INVALIDARG
ItemsView::OnScrollViewAnchorRequested
ItemsView.cpp:972, passes m_bringIntoViewElement to args.AnchorElement(...)
ScrollView::OnScrollPresenterAnchorRequested
ScrollPresenter::RaiseAnchorRequested
ScrollPresenter::EnsureAnchorElementSelection
```

In the OpenClaw dump, anchor selection is requested through `FlowLayoutAlgorithm::Measure` / `ViewportManagerWithPlatformFeatures::SuggestedAnchor`. The explicitly forced-layout reproduction reached the same throw through `ScrollPresenter::ArrangeOverride`. The surrounding layout stack can therefore differ even though the failing native anchor-validation path is the same.

The two captured ARM64 dumps have matching WinUI PDB identities and share the first 13 native stowed-stack frames, including the throwing instruction at `Microsoft.UI.Xaml.Controls.dll + 0x325E48`.

`ItemsView::OnScrollViewAnchorRequested` checks that its retained target is non-null, but passes it to the setter without checking whether it is still a valid anchor. `ScrollPresenter::IsElementValidAnchor` requires a visible element that is the content itself or a descendant of the content. In this minimal reproduction, the visibility condition is deliberately invalidated.

The original OpenClaw invalidation may involve collapsing or recycling/detaching a row; the precise original transition is not asserted by this reduced reproduction. The reduced case isolates the confirmed native failure.

Crash occurs at https://github.com/microsoft/microsoft-ui-xaml/blob/6d4e2040ea8f5a2bd8130cf24d3e23985f8f8ba3/controls/dev/ScrollPresenter/ScrollingAnchorRequestedEventArgs.cpp#L43
which is called from https://github.com/microsoft/microsoft-ui-xaml/blob/e8442d07ae57d2d3e653e616831f504937881bd3/src/controls/dev/ItemsView/ItemsView.cpp#L972

Repro sample:
[WinUI.ItemsViewAnchorRepro.zip](https://github.com/user-attachments/files/32148084/WinUI.ItemsViewAnchorRepro.zip)

### Reactor-based reproduction

A minimal, unpackaged C# Reactor reproduction with complete source is now tracked in [microsoft/microsoft-ui-reactor#1213](https://github.com/microsoft/microsoft-ui-reactor/issues/1213). It also links back to [openclaw/openclaw-windows-node#1167](https://github.com/openclaw/openclaw-windows-node/issues/1167).

In that sample, the application does not explicitly collapse any container or call `UpdateLayout`. It starts a tail `StartBringItemIntoView` request and replaces the keyed history through Reactor state. A diagnostic run identified Reactor's `ElementFactory.RecycleElement -> TryParkForPool -> ParkOrphan` changing the retained target from `Visible` to `Collapsed` during recycling.

The minimal unpackaged sample crashed on its first button activation in two fresh ARM64 Debug launches. Its native dump reaches this issue's `ScrollingAnchorRequestedEventArgs::AnchorElement` failure through `FlowLayoutAlgorithm::Measure` / `ViewportManagerWithPlatformFeatures::SuggestedAnchor`, with the same PDB identities and 24 matching leading Controls-module frames as the original OpenClaw dump.

The button deliberately compresses the overlap between a pending tail request and history replacement. This demonstrates a Reactor-triggered instance of the WinUI failure without claiming that the whole OpenClaw scheduling path, the separate sustained hang, or an independent Reactor defect has been established. Details, versions, control-experiment results, and source are in the linked Reactor issue.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.