dotnet/wpf · error · InvalidOperationException

SR.CannotMoveToUnknownPosition

Error message

SR.CannotMoveToUnknownPosition

What it means

A Move notification was raised with NewStartingIndex < 0, meaning the source collection reported an unknown destination index. ListCollectionView throws InvalidOperationException (SR.CannotMoveToUnknownPosition) because it cannot position the moved item.

Solutions

  1. Fix the Move event source to pass the actual zero-based destination index as NewStartingIndex.
  2. If the destination is unknown, raise Reset instead of Move.
  3. Catch InvalidOperationException around the update and call Refresh() to resynchronize the view.

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

if (args.Action == NotifyCollectionChangedAction.Move && args.NewStartingIndex < 0) { /* invalid move; use Reset or fix index */ }

Try / catch

try { /* handle move */ } catch (InvalidOperationException) { view.Refresh(); }

Prevention

When it happens

Trigger: The bound collection raises NotifyCollectionChangedAction.Move with a single NewItems item but NewStartingIndex == -1 or negative, typically from calling CollectionChanged manually or from a Move implementation that lost track of the index.

Common situations: Hand-raised Move events using NotifyCollectionChangedAction.Reset-style unknown-index (-1) conventions; ported collection code that always passes -1 for position.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/708ece6469bb7b41. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/ListCollectionView.cs:2518

                    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>
        /// Create, filter and sort the local index array.
        /// called from Refresh(), override in derived classes as needed.
        /// </summary>
        /// <param name="list">new ILIst to associate this view with</param>
        /// <returns>new local array to use for this view</returns>
        private void PrepareLocalArray()

View on GitHub (pinned to 81131a70a4)