dotnet/wpf · error · InvalidOperationException

throw new…

Error message

throw new InvalidOperationException(SR.CannotMoveToUnknownPosition);

What it means

A Move notification with a negative NewStartingIndex is invalid: the view cannot move an item to an unknown position. ValidateCollectionChangedEventArgs throws InvalidOperationException(SR.CannotMoveToUnknownPosition) in that case.

Solutions

  1. Fix the source to always supply a valid non-negative NewStartingIndex for Move events.
  2. Validate the target index before raising Move; if unknown, raise Remove + Add at the correct position instead.
  3. Assert index >= 0 in your move helper before constructing NotifyCollectionChangedEventArgs.

Example fix

// before
int idx = list.IndexOf(item); // -1 when missing
OnCollectionChanged(new NotifyCollectionChangedEventArgs(Move, item, idx));

// after
int idx = list.IndexOf(item);
if (idx >= 0)
    OnCollectionChanged(new NotifyCollectionChangedEventArgs(Move, item, idx));
Defensive patterns

Strategy: validation

Validate before calling

if (e.Action == NotifyCollectionChangedAction.Move && e.NewStartingIndex < 0)
    throw new InvalidOperationException("Move requires a non-negative NewStartingIndex");

Try / catch

try { view.ProcessCollectionChanged(e); }
catch (InvalidOperationException ex) when (ex.Message.Contains("move"))
{ RebuildView(); }

Prevention

When it happens

Trigger: A source collection fires CollectionChanged with Action=Move and NewStartingIndex < 0 (e.g. -1 from a MoveRange helper that failed to compute the target).

Common situations: Custom move implementations passing -1 when the target index could not be found; sort/reorder code that forwards an unset index.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Data/CompositeCollectionView.cs:1451

                    if (e.NewItems.Count != 1)
                        throw new NotSupportedException(SR.RangeActionsNotSupported);
                    break;

                case NotifyCollectionChangedAction.Remove:
                    if (e.OldItems.Count != 1)
                        throw new NotSupportedException(SR.RangeActionsNotSupported);
                    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:
                    throw new NotSupportedException(SR.Format(SR.UnexpectedCollectionChangeAction, e.Action));
            }
        }

        /// <summary>
        /// Helper to raise a PropertyChanged event  />).
        /// </summary>
        private void OnPropertyChanged(string propertyName)
        {
            OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
        }

View on GitHub (pinned to 81131a70a4)