{"record":{"id":"99556eb04bfe4006","repo":"dotnet/wpf","slug":"sr-enumerator-collectionchanged-textdecorationcollection","errorCode":null,"errorMessage":"SR.Enumerator_CollectionChanged","messagePattern":"SR\\.Enumerator_CollectionChanged","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Generated/TextDecorationCollection.cs","lineNumber":788,"sourceCode":"            {\n                _list.ReadPreamble();\n\n                if (_version == _list._version)\n                {\n                    if (_index > -2 && _index < _list._collection.Count - 1)\n                    {\n                        _current = _list._collection[++_index];\n                        return true;\n                    }\n                    else\n                    {\n                        _index = -2; // -2 indicates \"past the end\"\n                        return false;\n                    }\n                }\n                else\n                {\n                    throw new InvalidOperationException(SR.Enumerator_CollectionChanged);\n                }\n            }\n\n            /// <summary>\n            /// Sets the enumerator to its initial position, which is before the\n            /// first element in the collection.\n            /// </summary>\n            public void Reset()\n            {\n                _list.ReadPreamble();\n\n                if (_version == _list._version)\n                {\n                    _index = -1;\n                }\n                else\n                {\n                    throw new InvalidOperationException(SR.Enumerator_CollectionChanged);","sourceCodeStart":770,"sourceCodeEnd":806,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Generated/TextDecorationCollection.cs#L770-L806","documentation":"The collection's enumerator throws InvalidOperationException (SR.Enumerator_CollectionChanged) in MoveNext when the underlying collection's version stamp no longer matches the version captured when the enumerator was created. WPF collections fail fast on structural change during enumeration rather than risk undefined behavior.","triggerScenarios":"Calling Add/Insert/Remove/Clear on the TextDecorationCollection inside a foreach over it, then continuing to call MoveNext.","commonSituations":"Modifying decorations in a loop (e.g. removing all underline decorations while iterating); event handlers that mutate the collection during enumeration; UI code reacting to property changes triggered mid-loop.","solutions":["Snapshot the items before mutating: foreach (var d in collection.ToList()) { ... }","Iterate backwards over the indexed collection with a for loop when removing","Defer mutations until after enumeration completes"],"exampleFix":"// before\nforeach (var d in collection) if (IsUnwanted(d)) collection.Remove(d);\n// after\nforeach (var d in collection.ToList()) if (IsUnwanted(d)) collection.Remove(d);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try\n{\n    foreach (var d in collection) { /* ... */ }\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"changed\"))\n{\n    // re-enumerate over a snapshot: collection.ToList()\n}","preventionTips":["Never mutate the collection during foreach; snapshot with ToList() first","Remove in reverse with a for loop over the index","Defer collection edits triggered by events until enumeration ends"],"tags":["wpf","invalidoperationexception","enumerator","collection-modified"],"backgroundTag":"invalid-state-transition","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"}