dotnet/wpf · error · ArgumentOutOfRangeException
ArgumentOutOfRangeException
Error message
ArgumentOutOfRangeException
What it means
CollectionViewGroupInternal.LeafAt walks the group tree to locate the leaf at a given index; if the loop finishes without finding it, it throws ArgumentOutOfRangeException(nameof(index)), an internal invariant that the requested leaf index is outside the group's leaf range.
Solutions
- Ensure all source collection mutations happen on the UI thread or via INotifyCollectionChanged
- Re-fetch the collection view / refresh grouping after mutating data
- Bounds-check index against the view's Count before indexing
Example fix
// before var item = groupedView.Items[view.Count - 1 + 1]; // stale count // after int i = view.Count - 1; if (i >= 0) var item = groupedView.Items[i];
Defensive patterns
Strategy: validation
Validate before calling
if (index >= 0 && index < view.Count) { var item = view.GetItemAt(index); } Type guard
bool LeafIndexExists(ICollectionView view, int i) => i >= 0 && i < view.Count;
Try / catch
try { var item = group.LeafAt(index); } catch (ArgumentOutOfRangeException) { /* group changed; re-fetch view */ } Prevention
- Bounds-check against the view's Count before indexing
- Mutate grouped sources only on the UI thread
- Refresh the view after bulk data changes
When it happens
Trigger: Requesting a leaf index >= total leaf count of the group, typically via collection view indexing after the group contents changed without the view being notified.
Common situations: Accessing ItemsControl items or CollectionView[i] after mutating grouped source collection off the UI thread; stale snapshots of groups; custom views bypassing change notification.
Related errors
- SR.MemberNotAllowedDuringAddOrEdit (formatted with…
- args
- args
- ArgumentOutOfRangeException(authenticationType)
- ArgumentOutOfRangeException(nameof(characterHit))
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/b4bb0c08582f55f8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Data/CollectionViewGroupInternal.cs:351
index -= subgroup.ItemCount;
}
}
else
{
// current item is a leaf - see if we're done
if (index == 0)
{
return Items[k];
}
else
{
index -= 1;
}
}
}
// the loop should have found the index. We shouldn't get here.
throw new ArgumentOutOfRangeException(nameof(index));
}
// return an enumerator over the leaves governed by this group
internal IEnumerator GetLeafEnumerator()
{
return new LeafEnumerator(this);
}
// insert a new item or subgroup and return its index. Seed is a
// representative from the subgroup (or the item itself) that
// is used to position the new item/subgroup w.r.t. the order given
// by the comparer. (If comparer is null, just add at the end).
internal int Insert(object item, object seed, IComparer comparer)
{
// when group sorting is not declared,
// never insert the new item/group before the explicit subgroups
int low = 0;
if (_groupComparer == null && GroupBy != null)View on GitHub (pinned to 81131a70a4)