dotnet/wpf · error · NotSupportedException

SR.Format(SR.UnexpectedCollectionChangeAction, e.Action)

Error message

SR.Format(SR.UnexpectedCollectionChangeAction, e.Action)

What it means

CollectionView.ProcessCollectionChanged handles Add, Remove, Replace, Move and Reset. Any other NotifyCollectionChangedAction value reaching it falls into the default case and throws NotSupportedException with UnexpectedCollectionChangeAction. Since the enum has no other standard values, this guards against corrupt or synthetic events.

Solutions

  1. Only raise events with valid NotifyCollectionChangedAction values (Add, Remove, Replace, Move, Reset)
  2. Audit custom INotifyCollectionChanged implementations for uninitialized enum fields
  3. Validate enum values before constructing NotifyCollectionChangedEventArgs

Example fix

// before
var action = (NotifyCollectionChangedAction)rawValue; // may be invalid
// after
if (Enum.IsDefined(typeof(NotifyCollectionChangedAction), rawValue))
    var action = (NotifyCollectionChangedAction)rawValue;
Defensive patterns

Strategy: validation

Validate before calling

bool isValidAction(NotifyCollectionChangedAction a) => a is NotifyCollectionChangedAction.Add or NotifyCollectionChangedAction.Remove or NotifyCollectionChangedAction.Replace or NotifyCollectionChangedAction.Move or NotifyCollectionChangedAction.Reset;

Type guard

static bool IsDefinedAction(NotifyCollectionChangedAction a) => Enum.IsDefined(typeof(NotifyCollectionChangedAction), a);

Try / catch

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

Prevention

When it happens

Trigger: A NotifyCollectionChangedEventArgs with an out-of-range or undefined action value is passed to the view, e.g. by casting an arbitrary int to NotifyCollectionChangedAction or via reflection-based event raising.

Common situations: Testing frameworks or mocking libraries fabricating change events with invalid enum values; binary/formatter deserialization producing corrupt enum values; hand-written event args with an uninitialized enum field (0 if not assigned to a valid action).

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

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

                    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)
            {
                ++_currentPosition;

                if (_currentPosition < Count)
                {
                    _currentItem = EnumerableWrapper[_currentPosition];
                }
            }

View on GitHub (pinned to 81131a70a4)