dotnet/wpf · error · InvalidOperationException

SR.CannotMoveToUnknownPosition

Error message

SR.CannotMoveToUnknownPosition

What it means

When a source collection raises a Move event, CollectionView requires a valid target index. If NewStartingIndex is negative (unknown, -1), the view cannot place the moved item and throws InvalidOperationException with CannotMoveToUnknownPosition.

Solutions

  1. Ensure Move events are raised with a valid non-negative NewStartingIndex
  2. If the new position is unknown, raise Reset instead
  3. Assert/validate the computed target index before raising the event

Example fix

// before
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, item, -1, oldIndex));
// after
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Move, item, newIndex, oldIndex));
Defensive patterns

Strategy: validation

Validate before calling

bool isValidMoveIndex(NotifyCollectionChangedEventArgs e) => e.Action != NotifyCollectionChangedAction.Move || e.NewStartingIndex >= 0;

Type guard

static bool HasKnownMoveTarget(NotifyCollectionChangedEventArgs e) => e.Action == NotifyCollectionChangedAction.Move && e.NewStartingIndex >= 0;

Try / catch

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

Prevention

When it happens

Trigger: A bound collection raises NotifyCollectionChangedAction.Move with NewStartingIndex = -1, typically from a custom collection that constructs the args without specifying the new index.

Common situations: Custom observable collections raising Move events with default/unknown index arguments; refactored collection code where the new position was computed as -1 on failure.

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

Appendix: source

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

                    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:
                    throw new NotSupportedException(SR.Format(SR.UnexpectedCollectionChangeAction, e.Action));
            }
        }

        // fix up CurrentPosition and CurrentItem after a collection change
        private void AdjustCurrencyForAdd(int index)
        {
            // adjust current index if insertion is earlier
            if (Count == 1)
                _currentPosition = -1;
            else if (index <= _currentPosition)
            {

View on GitHub (pinned to 81131a70a4)