dotnet/wpf · error · NotSupportedException
SR.Format(SR.UnexpectedCollectionChangeAction, e.Action)
Error message
SR.Format(SR.UnexpectedCollectionChangeAction, e.Action)
What it means
When ItemCollection syncs its internal clone with the underlying view, it clones the change-log for Add/Remove/Replace/Reset actions. Any other NotifyCollectionChangedAction reaches a default case that throws NotSupportedException(SR.UnexpectedCollectionChangeAction, e.Action) — an internal-invariant guard against malformed change notifications.
Solutions
- Fix the custom INotifyCollectionChanged implementation to raise only valid actions with correctly built EventArgs
- Use ObservableCollection or a well-tested observable collection implementation
- If you control the event, ensure e.Action is Add, Remove, Replace, or Reset
Example fix
// before RaiseCollectionChanged(new NotifyCollectionChangedEventArgs((NotifyCollectionChangedAction)9)); // after RaiseCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
Defensive patterns
Strategy: try-catch
Validate before calling
if (Enum.IsDefined(typeof(NotifyCollectionChangedAction), e.Action) && e.Action != NotifyCollectionChangedAction.Move) { /* handled */ } Type guard
bool isSupportedAction = e.Action is NotifyCollectionChangedAction.Add or NotifyCollectionChangedAction.Remove or NotifyCollectionChangedAction.Replace or NotifyCollectionChangedAction.Reset;
Try / catch
try { /* sync with view */ } catch (NotSupportedException ex) { /* bad INotifyCollectionChanged source: replace or fix source */ } Prevention
- Use ObservableCollection rather than hand-rolled INotifyCollectionChanged
- Raise only well-formed NotifyCollectionChangedEventArgs
- Test custom collections against ItemsControl consumers
When it happens
Trigger: A source collection (or custom INotifyCollectionChanged implementation) raising NotifyCollectionChangedEventArgs with an unexpected or invalid Action value that the clone logic does not handle.
Common situations: Implementing INotifyCollectionChanged yourself and firing events with wrong/misbuilt args; third-party observable collections that raise nonstandard notifications.
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
- SR.CannotFindRemovedItem
- SR.Format(SR.CollectionAddEventMissingItem, item)
- SR.Format(SR.UnexpectedCollectionChangeAction, args.Action)
- SR.Freezable_UnexpectedChange
- SR.Generator_Inconsistent
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/a9f81e5d76d7f34e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemCollection.cs:2229
{
clone.RemoveAt(e.OldStartingIndex);
}
for (int i = 0; i < e.NewItems.Count; i++)
{
clone.Insert(e.NewStartingIndex + i, (T)e.NewItems[i]);
}
}
break;
// this arm also handles cases where the two collections have gotten
// out of sync (typically because exceptions prevented a previous sync
// from happening)
case NotifyCollectionChangedAction.Reset:
CloneList(clone, origin);
break;
default:
throw new NotSupportedException(SR.Format(SR.UnexpectedCollectionChangeAction, e.Action));
}
}
private void CloneList(IList clone, IList master)
{
// if either party is null, do nothing. Allowing null lets the caller
// avoid a lazy instantiation of the Sort/Group description collection.
if (clone == null || master == null)
return;
if (clone.Count > 0)
{
clone.Clear();
}
for (int i = 0, n = master.Count; i < n; ++i)
{
clone.Add(master[i]);View on GitHub (pinned to 81131a70a4)