dotnet/wpf · error · InvalidOperationException
SR.AddedItemNotAtIndex (formatted with index)
Error message
SR.AddedItemNotAtIndex (formatted with index)
What it means
An Add notification supplied an index, but verification found the item at that index in the source list is not the announced new item (reference/equality check via ItemsControl.EqualsEx fails). ListCollectionView throws InvalidOperationException with SR.AddedItemNotAtIndex.
Solutions
- Pass the true index where the item now sits in the source list, verified after the actual insert.
- Pass -1 as NewStartingIndex to let the view locate the item via IndexOf.
- Ensure EqualsEx semantics: use the same instance or value-equal item in the event as inserted.
Example fix
// before (index guessed) OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, sortedPositionGuess)); // after var actualIndex = Items.IndexOf(item); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, actualIndex));
Defensive patterns
Strategy: validation
Validate before calling
if (args.Action == NotifyCollectionChangedAction.Add && args.NewStartingIndex >= 0 && !ReferenceEquals(sourceList[args.NewStartingIndex], args.NewItems[0])) { /* index mismatch; use Reset */ } Try / catch
try { /* process add */ } catch (InvalidOperationException) { view.Refresh(); } Prevention
- Determine the actual post-insert index (IndexOf) before raising the event
- Pass -1 to let the view locate the item when unsure
- Raise events only after the list mutation is committed
When it happens
Trigger: Raising NotifyCollectionChangedAction.Add with NewStartingIndex i where ilFull[i] does not equal the NewItems[0] object — e.g. event raised with a stale index, or the item was inserted at a different position than reported.
Common situations: Sorted/filtered custom collections whose insertion position differs from the reported index; event args reused or cached with an outdated index; double insertion where the second insert shifts indices.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- SR.AddedItemNotInCollection
- SR.BindingListCannotCustomFilter
- SR.BindingListCanOnlySortByOneProperty
- SR.CannotMoveToUnknownPosition
- SR.CannotMoveToUnknownPosition
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/5b569a6f4f115cf0.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/ListCollectionView.cs:2673
return (NewItemPlaceholderPosition == NewItemPlaceholderPosition.AtBeginning)
? 1 : UsesLocalArray ? InternalCount - 2 : index;
}
int delta = IsGrouping ? 0 :
(NewItemPlaceholderPosition == NewItemPlaceholderPosition.AtBeginning)
? (IsAddingNew ? 2 : 1) : 0;
IList ilFull = (AllowsCrossThreadChanges ? ShadowCollection : SourceCollection) as IList;
// validate input
if (index < -1 || index > ilFull.Count)
throw new InvalidOperationException(SR.Format(SR.CollectionChangeIndexOutOfRange, index, ilFull.Count));
if (action == NotifyCollectionChangedAction.Add)
{
if (index >= 0)
{
if (!System.Windows.Controls.ItemsControl.EqualsEx(item, ilFull[index]))
throw new InvalidOperationException(SR.Format(SR.AddedItemNotAtIndex, index));
}
else
{
// event didn't specify index - determine it the hard way
index = ilFull.IndexOf(item);
if (index < 0)
throw new InvalidOperationException(SR.AddedItemNotInCollection);
}
}
// if there's no sort or filter, use the index into the full array
if (!UsesLocalArray)
{
if (IsAddingNew)
{
if (NewItemPlaceholderPosition != NewItemPlaceholderPosition.None &&
index > _newItemIndex)
{View on GitHub (pinned to 81131a70a4)