dotnet/wpf · critical · InvalidOperationException
SR.Format(SR.CollectionAddEventMissingItem, item)
Error message
SR.Format(SR.CollectionAddEventMissingItem, item)
What it means
When handling a CollectionChanged Add event, the generator must determine the index of the added item. If the event's NewStartingIndex was not supplied (index < 0), it falls back to ItemsInternal.IndexOf(item); if the item is not found in the Items collection, it throws InvalidOperationException (CollectionAddEventMissingItem), because the add event references an item the collection does not contain.
Solutions
- Always supply a valid NewStartingIndex when raising Add events, or ensure the item is already inserted before the event fires.
- Fix the custom collection so events reflect the post-change state (item present at reported index).
- Use ObservableCollection or a battle-tested collection wrapper instead of hand-rolled INotifyCollectionChanged.
Example fix
// before OnCollectionChanged(new NotifyCollectionChangedEventArgs(Add, item, -1)); // item not yet inserted // after items.Insert(index, item); OnCollectionChanged(new NotifyCollectionChangedEventArgs(Add, item, index));
Defensive patterns
Strategy: validation
Validate before calling
// In your INotifyCollectionChanged source, before raising Add:
if (newStartingIndex < 0 && !items.Contains(item))
throw new InvalidOperationException("Add event must reference an item present in the collection"); Try / catch
try { /* process add event */ }
catch (InvalidOperationException ex) when (ex.Message.Contains("add event"))
{
itemsControl.Items.Refresh();
} Prevention
- Insert the item into the collection BEFORE raising the Add event.
- Always set NewStartingIndex explicitly.
- Prefer ObservableCollection over hand-rolled notification code.
When it happens
Trigger: A source collection raises NotifyCollectionChangedAction.Add with NewStartingIndex = -1 and an item that is not actually present in the Items collection — typically from a custom INotifyCollectionChanged implementation raising stale or mismatched events.
Common situations: Custom collections firing Add events for items before actually inserting them; event replay/caching layers that duplicate or reorder notifications; GroupStyle scenarios where events come from the wrong collection.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- SR.CannotFindRemovedItem
- SR.Generator_Inconsistent
- SR.RangeActionsNotSupported
- SR.CannotRecyleHeterogeneousTypes
- SR.Format(SR.CannotRemoveUnrealizedItems, index, count)
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/5ff6ce16381a1e1f.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemContainerGenerator.cs:2375
else
{
OnRefresh();
}
}
private void ValidateAndCorrectIndex(object item, ref int index)
{
if (index >= 0)
{
// this check is expensive - Items[index] potentially iterates through
// the collection. So trust the sender to tell us the truth in retail bits.
Debug.Assert(ItemsControl.EqualsEx(item, ItemsInternal[index]), "Event contains the wrong index");
}
else
{
index = ItemsInternal.IndexOf(item);
if (index < 0)
throw new InvalidOperationException(SR.Format(SR.CollectionAddEventMissingItem, item));
}
}
/// <summary>
/// Forward a CollectionChanged event
/// </summary>
// Called when items collection changes.
private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
{
if (sender != ItemsInternal && args.Action != NotifyCollectionChangedAction.Reset)
return; // ignore events (except Reset) from ItemsCollection when we're listening to group's items.
switch (args.Action)
{
case NotifyCollectionChangedAction.Add:
if (args.NewItems.Count != 1)
throw new NotSupportedException(SR.RangeActionsNotSupported);
OnItemAdded(args.NewItems[0], args.NewStartingIndex);View on GitHub (pinned to 81131a70a4)