{"record":{"id":"cfc8364dd619a9c0","repo":"dotnet/wpf","slug":"sr-format-sr-unexpectedcollectionchangeaction-args-action","errorCode":null,"errorMessage":"SR.Format(SR.UnexpectedCollectionChangeAction, args.Action)","messagePattern":"SR\\.Format\\(SR\\.UnexpectedCollectionChangeAction, args\\.Action\\)","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemContainerGenerator.cs","lineNumber":2427,"sourceCode":"                    OnItemReplaced(args.OldItems[0], args.NewItems[0], args.NewStartingIndex);\n                    break;\n\n                case NotifyCollectionChangedAction.Move:\n                    // Don't check arguments if app targets 4.0, for compat ( 726682)\n                    if (!FrameworkCompatibilityPreferences.TargetsDesktop_V4_0)\n                    {\n                        if (args.OldItems.Count != 1)\n                            throw new NotSupportedException(SR.RangeActionsNotSupported);\n                    }\n                    OnItemMoved(args.OldItems[0], args.OldStartingIndex, args.NewStartingIndex);\n                    break;\n\n                case NotifyCollectionChangedAction.Reset:\n                    OnRefresh();\n                    break;\n\n                default:\n                    throw new NotSupportedException(SR.Format(SR.UnexpectedCollectionChangeAction, args.Action));\n            }\n\n            PresentationTraceLevel traceLevel = PresentationTraceSources.GetTraceLevel(this);\n            if (traceLevel >= PresentationTraceLevel.High)\n            {\n                Verify();\n            }\n        }\n\n        // Called when an item is added to the items collection\n        private void OnItemAdded(object item, int index)\n        {\n            if (_itemMap == null)\n            {\n                // reentrant call (from RemoveAllInternal) shouldn't happen,\n                // but if it does, don't crash\n                Debug.Fail(\"unexpected reentrant call to OnItemAdded\");\n                return;","sourceCodeStart":2409,"sourceCodeEnd":2445,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemContainerGenerator.cs#L2409-L2445","documentation":"ItemContainerGenerator's collection-changed handler switches over NotifyCollectionChangedAction and handles Add, Remove, Replace, Move, and Reset. Any other value of the enum (or an invalid cast value from a misbehaving collection) falls through to the default case, which throws NotSupportedException with 'UnexpectedCollectionChangeAction'. This is effectively an internal-invariant guard: the WPF generator simply has no code path for the action it received.","triggerScenarios":"A custom INotifyCollectionChanged collection raising a NotifyCollectionChangedEventArgs with an out-of-range/undefined NotifyCollectionChangedAction value (e.g. cast of an invalid int), or a collection passing an action the generator does not recognize after the known cases.","commonSituations":"Hand-rolled or third-party observable collections that construct NotifyCollectionChangedEventArgs manually with an unhandled or corrupted action value; binary-incompatible libraries emitting new/unknown action values into older WPF.","solutions":["Fix the source collection so it only raises valid NotifyCollectionChangedAction values (Add, Remove, Replace, Move, Reset).","Use NotifyCollectionChangedEventArgs' public static factory methods (Add/Remove/Replace/Move/Reset) instead of constructing the event args manually.","Use ObservableCollection<T> to guarantee well-formed change notifications.","Audit third-party collection libraries for versions that emit custom/invalid action values."],"exampleFix":"// before\nvar e = new NotifyCollectionChangedEventArgs((NotifyCollectionChangedAction)99);\n\n// after\nvar e = NotifyCollectionChangedEventArgs.Reset(); // or Add/Remove/Replace/Move factory methods","handlingStrategy":"validation","validationCode":"if (!Enum.IsDefined(typeof(NotifyCollectionChangedAction), args.Action))\n    throw new InvalidOperationException(\"Invalid NotifyCollectionChangedAction value\");","typeGuard":"bool IsValidAction(NotifyCollectionChangedAction a) =>\n    a is NotifyCollectionChangedAction.Add\n       or NotifyCollectionChangedAction.Remove\n       or NotifyCollectionChangedAction.Replace\n       or NotifyCollectionChangedAction.Move\n       or NotifyCollectionChangedAction.Reset;","tryCatchPattern":"try { SubscribeGenerator(collection); }\ncatch (NotSupportedException ex) when (ex.Message.Contains(\"UnexpectedCollectionChangeAction\"))\n{\n    // collection emits malformed events; resubscribe to a sanitized wrapper\n    SubscribeGenerator(new SanitizingObservableCollection(collection));\n}","preventionTips":["Use NotifyCollectionChangedEventArgs static factory methods instead of raw constructors","Validate action values in custom collection event-raising code","Do not cast arbitrary ints to NotifyCollectionChangedAction","Pin third-party collection library versions known to emit standard actions"],"tags":["wpf","inotifycollectionchanged","invalid-enum","itemscontrol"],"backgroundTag":"unsupported-enum-value","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}