{"record":{"id":"5ff6ce16381a1e1f","repo":"dotnet/wpf","slug":"sr-format-sr-collectionaddeventmissingitem-item","errorCode":null,"errorMessage":"SR.Format(SR.CollectionAddEventMissingItem, item)","messagePattern":"SR\\.Format\\(SR\\.CollectionAddEventMissingItem, item\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"critical","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemContainerGenerator.cs","lineNumber":2375,"sourceCode":"            else\n            {\n                OnRefresh();\n            }\n        }\n\n        private void ValidateAndCorrectIndex(object item, ref int index)\n        {\n            if (index >= 0)\n            {\n                // this check is expensive - Items[index] potentially iterates through\n                // the collection.  So trust the sender to tell us the truth in retail bits.\n                Debug.Assert(ItemsControl.EqualsEx(item, ItemsInternal[index]), \"Event contains the wrong index\");\n            }\n            else\n            {\n                index = ItemsInternal.IndexOf(item);\n                if (index < 0)\n                    throw new InvalidOperationException(SR.Format(SR.CollectionAddEventMissingItem, item));\n            }\n        }\n\n        /// <summary>\n        /// Forward a CollectionChanged event\n        /// </summary>\n        // Called  when items collection changes.\n        private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args)\n        {\n            if (sender != ItemsInternal && args.Action != NotifyCollectionChangedAction.Reset)\n                return;     // ignore events (except Reset) from ItemsCollection when we're listening to group's items.\n\n            switch (args.Action)\n            {\n                case NotifyCollectionChangedAction.Add:\n                    if (args.NewItems.Count != 1)\n                        throw new NotSupportedException(SR.RangeActionsNotSupported);\n                    OnItemAdded(args.NewItems[0], args.NewStartingIndex);","sourceCodeStart":2357,"sourceCodeEnd":2393,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemContainerGenerator.cs#L2357-L2393","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nOnCollectionChanged(new NotifyCollectionChangedEventArgs(Add, item, -1)); // item not yet inserted\n\n// after\nitems.Insert(index, item);\nOnCollectionChanged(new NotifyCollectionChangedEventArgs(Add, item, index));","handlingStrategy":"validation","validationCode":"// In your INotifyCollectionChanged source, before raising Add:\nif (newStartingIndex < 0 && !items.Contains(item))\n    throw new InvalidOperationException(\"Add event must reference an item present in the collection\");","typeGuard":null,"tryCatchPattern":"try { /* process add event */ }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"add event\"))\n{\n    itemsControl.Items.Refresh();\n}","preventionTips":["Insert the item into the collection BEFORE raising the Add event.","Always set NewStartingIndex explicitly.","Prefer ObservableCollection over hand-rolled notification code."],"tags":["wpf","itemcontainergenerator","collection-changed","event"],"backgroundTag":"internal-invariant-violation","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}