{"record":{"id":"0593bf2655a07233","repo":"AvaloniaUI/Avalonia","slug":"reset-called-on-collection-without-reset-handler","errorCode":null,"errorMessage":"Reset called on collection without reset handler.","messagePattern":"Reset called on collection without reset handler\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Avalonia.Base/Collections/AvaloniaDictionaryExtensions.cs","lineNumber":83,"sourceCode":"                {\n                    case NotifyCollectionChangedAction.Add:\n                        Add(e.NewItems!);\n                        break;\n\n                    case NotifyCollectionChangedAction.Move:\n                    case NotifyCollectionChangedAction.Replace:\n                        Remove(e.OldItems!);\n                        Add(e.NewItems!);\n                        break;\n\n                    case NotifyCollectionChangedAction.Remove:\n                        Remove(e.OldItems!);\n                        break;\n\n                    case NotifyCollectionChangedAction.Reset:\n                        if (reset == null)\n                        {\n                            throw new InvalidOperationException(\n                                \"Reset called on collection without reset handler.\");\n                        }\n\n                        reset();\n                        Add(collection);\n                        break;\n                }\n            };\n\n            Add(collection);\n\n            if (weakSubscription)\n            {\n                return collection.WeakSubscribe(handler);\n            }\n            else\n            {\n                collection.CollectionChanged += handler;","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Avalonia.Base/Collections/AvaloniaDictionaryExtensions.cs#L65-L101","documentation":"InvalidOperationException thrown by AvaloniaDictionaryExtensions.ForEachItem when the observed dictionary raises a Reset collection-changed event but the caller did not supply a reset callback. ForEachItem needs a reset handler to know how to rebuild its tracked state after a wholesale clear/reset.","triggerScenarios":"Calling collection.ForEachItem(added, removed, reset: null) (or omitting reset) on a dictionary that later has Clear() called, which raises NotifyCollectionChangedAction.Reset.","commonSituations":"Tracking a dictionary that can be cleared by the view model; using the 2-action overload which forwards a null reset; a resource dictionary or styles collection being reset during theme reload.","solutions":["Provide a non-null reset Action that clears your tracked state (it will be followed by Add callbacks for surviving items).","Prevent the source dictionary from being cleared, or unsubscribe before clearing and re-subscribe after.","If reset truly cannot occur, document it; otherwise always pass a reset handler."],"exampleFix":"// before\ndict.ForEachItem(OnAdd, OnRemove, reset: null);\n\n// after\ndict.ForEachItem(OnAdd, OnRemove, () => { tracked.Clear(); });","handlingStrategy":"validation","validationCode":"if (canReset) collection.ForEachItem(OnAdd, OnRemove, () => tracked.Clear()); else /* avoid observing clearable dictionary */","typeGuard":null,"tryCatchPattern":"try { dict.ForEachItem(OnAdd, OnRemove, ResetHandler); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"reset handler\")) { /* rebuild state manually */ }","preventionTips":["Always pass a reset Action when the dictionary may be cleared.","Document which collections are safe to clear while observed.","Unsubscribe before a known clear and re-subscribe after."],"tags":["avalonia","collections","dictionary","reactive","collection-changed"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}