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

  1. Pass the true index where the item now sits in the source list, verified after the actual insert.
  2. Pass -1 as NewStartingIndex to let the view locate the item via IndexOf.
  3. 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

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


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)