{"record":{"id":"f41b7313a43ee1f4","repo":"dotnet/wpf","slug":"sr-removeditemnotfound","errorCode":null,"errorMessage":"SR.RemovedItemNotFound","messagePattern":"SR\\.RemovedItemNotFound","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/CollectionView.cs","lineNumber":1959,"sourceCode":"            _tempChangeLog = s_emptyList;\n\n            return null;\n        }\n\n        private void ValidateCollectionChangedEventArgs(NotifyCollectionChangedEventArgs e)\n        {\n            switch (e.Action)\n            {\n                case NotifyCollectionChangedAction.Add:\n                    if (e.NewItems.Count != 1)\n                        throw new NotSupportedException(SR.RangeActionsNotSupported);\n                    break;\n\n                case NotifyCollectionChangedAction.Remove:\n                    if (e.OldItems.Count != 1)\n                        throw new NotSupportedException(SR.RangeActionsNotSupported);\n                    if (e.OldStartingIndex < 0)\n                        throw new InvalidOperationException(SR.RemovedItemNotFound);\n                    break;\n\n                case NotifyCollectionChangedAction.Replace:\n                    if (e.NewItems.Count != 1 || e.OldItems.Count != 1)\n                        throw new NotSupportedException(SR.RangeActionsNotSupported);\n                    break;\n\n                case NotifyCollectionChangedAction.Move:\n                    if (e.NewItems.Count != 1)\n                        throw new NotSupportedException(SR.RangeActionsNotSupported);\n                    if (e.NewStartingIndex < 0)\n                        throw new InvalidOperationException(SR.CannotMoveToUnknownPosition);\n                    break;\n\n                case NotifyCollectionChangedAction.Reset:\n                    break;\n\n                default:","sourceCodeStart":1941,"sourceCodeEnd":1977,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/CollectionView.cs#L1941-L1977","documentation":"CollectionView.ProcessCollectionChanged validates INotifyCollectionChanged events before applying them. A Remove event must carry the starting index of the removed item; when OldStartingIndex is negative (Unknown/-1) the view cannot determine what was removed. The library throws InvalidOperationException because the source collection raised a malformed change event.","triggerScenarios":"A collection bound to a CollectionView raises NotifyCollectionChangedAction.Remove with Action=Remove but NewStartingIndex/OldStartingIndex set to -1 (e.g. built via NotifyCollectionChangedEventHandler args manually or a custom ObservableCollection implementation that reports unknown index).","commonSituations":"Custom observable collections that construct NotifyCollectionChangedEventArgs with NotifyCollectionChangedAction.Reset semantics but send Remove; third-party collection implementations that don't track indices; manual raising of CollectionChanged events with default (unknown) index arguments.","solutions":["Fix the source collection to raise Remove events with a valid, non-negative OldStartingIndex","If the index is truly unknown, raise Reset instead of Remove","Use ObservableCollection (or derive from it) instead of hand-rolled INotifyCollectionChanged implementations","Verify no code constructs NotifyCollectionChangedEventArgs.Remove with -1 as the index"],"exampleFix":"// before\ncollection.OnCollectionChanged(NotifyCollectionChangedAction.Remove, item, -1);\n// after\ncollection.OnCollectionChanged(NotifyCollectionChangedAction.Remove, item, indexToRemoveAt);","handlingStrategy":"validation","validationCode":"bool isValidRemove(NotifyCollectionChangedEventArgs e) => e.Action != NotifyCollectionChangedAction.Remove || (e.OldItems?.Count == 1 && e.OldStartingIndex >= 0);","typeGuard":"static bool HasKnownRemoveIndex(NotifyCollectionChangedEventArgs e) => e.Action == NotifyCollectionChangedAction.Remove && e.OldStartingIndex >= 0;","tryCatchPattern":"try { view.RefreshOrProcessChange(e); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"RemovedItemNotFound\")) { view.Refresh(); }","preventionTips":["Use ObservableCollection rather than hand-rolled INotifyCollectionChanged implementations","Never construct change args with unknown indices; prefer Reset when the index is unavailable","Unit-test custom collections against a CollectionView consumer"],"tags":["wpf","data-binding","collectionview","invalid-argument-value"],"backgroundTag":"invalid-argument-value","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"}