dotnet/wpf · error · InvalidOperationException
SR.Freezable_UnexpectedChange
Error message
SR.Freezable_UnexpectedChange
What it means
OnCollectionChanged raises InvalidOperationException(SR.Freezable_UnexpectedChange) when it receives a NotifyCollectionChangedAction other than Add, Remove, Replace, Move, or Reset (i.e. the default/unknown action). This is an internal invariant: the WPF code constructs the args itself, so this signals a corrupted or unforeseen change action, not a caller mistake.
Solutions
- Audit code that constructs NotifyCollectionChangedEventArgs and always pass an explicit valid NotifyCollectionChangedAction.
- Do not route foreign INotifyCollectionChanged events through FreezableCollection.OnCollectionChanged.
- If it appears without custom code, report it as a WPF bug and capture a stack trace of the raising operation.
Example fix
// before var args = new NotifyCollectionChangedEventArgs(default, item); // after var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item);
Defensive patterns
Strategy: validation
Validate before calling
if (!Enum.IsDefined(typeof(NotifyCollectionChangedAction), action) || action == default)
throw new ArgumentException("action must be an explicit NotifyCollectionChangedAction value"); Type guard
static bool IsValidAction(NotifyCollectionChangedAction a) => a is NotifyCollectionChangedAction.Add or Remove or Replace or Move or Reset;
Try / catch
try { OnCollectionChanged(args); }
catch (InvalidOperationException ex) when (ex.Message.Contains("change")) { log.Error("Unexpected change action", ex); } Prevention
- Always construct NotifyCollectionChangedEventArgs with an explicit action
- Never pass default(NotifyCollectionChangedAction)
- Do not bridge foreign collection-change events into FreezableCollection internals
When it happens
Trigger: A change-notification pipeline (Clear, Insert, Remove, RemoveAt, AddHelper) delivering an unrecognized NotifyCollectionChangedAction to OnCollectionChanged — practically only via custom NotifyCollectionChangedEventArgs with default action or future/invalid enum values.
Common situations: Custom collection-change plumbing that builds NotifyCollectionChangedEventArgs without specifying an action, enum casting bugs, mixing WPF FreezableCollection with code assuming different enum semantics.
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.Generator_Inconsistent
- Animation_UnrecognizedHandoffBehavior
- args
- ArgumentOutOfRangeException(authentication)
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/e88028071ce938e4.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/FreezableCollection.cs:754
{
NotifyCollectionChangedEventArgs args;
switch (action)
{
case NotifyCollectionChangedAction.Reset:
args = new NotifyCollectionChangedEventArgs(action);
break;
case NotifyCollectionChangedAction.Add:
args = new NotifyCollectionChangedEventArgs(action, newValue, newIndex);
break;
case NotifyCollectionChangedAction.Remove:
args = new NotifyCollectionChangedEventArgs(action, oldValue, oldIndex);
break;
case NotifyCollectionChangedAction.Replace:
args = new NotifyCollectionChangedEventArgs(action, newValue, oldValue, newIndex);
break;
default:
throw new InvalidOperationException(SR.Freezable_UnexpectedChange);
}
OnCollectionChanged(args);
}
}
}
#endregion Private Helpers
//------------------------------------------------------
//
// Protected Methods
//
//------------------------------------------------------
#region Protected Methods
View on GitHub (pinned to 81131a70a4)