dotnet/wpf · error · InvalidOperationException

SR.RemovedItemNotFound

Error message

SR.RemovedItemNotFound

What it means

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.

Solutions

  1. Fix the source collection to raise Remove events with a valid, non-negative OldStartingIndex
  2. If the index is truly unknown, raise Reset instead of Remove
  3. Use ObservableCollection (or derive from it) instead of hand-rolled INotifyCollectionChanged implementations
  4. Verify no code constructs NotifyCollectionChangedEventArgs.Remove with -1 as the index

Example fix

// before
collection.OnCollectionChanged(NotifyCollectionChangedAction.Remove, item, -1);
// after
collection.OnCollectionChanged(NotifyCollectionChangedAction.Remove, item, indexToRemoveAt);
Defensive patterns

Strategy: validation

Validate before calling

bool isValidRemove(NotifyCollectionChangedEventArgs e) => e.Action != NotifyCollectionChangedAction.Remove || (e.OldItems?.Count == 1 && e.OldStartingIndex >= 0);

Type guard

static bool HasKnownRemoveIndex(NotifyCollectionChangedEventArgs e) => e.Action == NotifyCollectionChangedAction.Remove && e.OldStartingIndex >= 0;

Try / catch

try { view.RefreshOrProcessChange(e); } catch (InvalidOperationException ex) when (ex.Message.Contains("RemovedItemNotFound")) { view.Refresh(); }

Prevention

When it happens

Trigger: 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).

Common situations: 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.

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/f41b7313a43ee1f4. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/CollectionView.cs:1959

            _tempChangeLog = s_emptyList;

            return null;
        }

        private void ValidateCollectionChangedEventArgs(NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    if (e.NewItems.Count != 1)
                        throw new NotSupportedException(SR.RangeActionsNotSupported);
                    break;

                case NotifyCollectionChangedAction.Remove:
                    if (e.OldItems.Count != 1)
                        throw new NotSupportedException(SR.RangeActionsNotSupported);
                    if (e.OldStartingIndex < 0)
                        throw new InvalidOperationException(SR.RemovedItemNotFound);
                    break;

                case NotifyCollectionChangedAction.Replace:
                    if (e.NewItems.Count != 1 || e.OldItems.Count != 1)
                        throw new NotSupportedException(SR.RangeActionsNotSupported);
                    break;

                case NotifyCollectionChangedAction.Move:
                    if (e.NewItems.Count != 1)
                        throw new NotSupportedException(SR.RangeActionsNotSupported);
                    if (e.NewStartingIndex < 0)
                        throw new InvalidOperationException(SR.CannotMoveToUnknownPosition);
                    break;

                case NotifyCollectionChangedAction.Reset:
                    break;

                default:

View on GitHub (pinned to 81131a70a4)