{"record":{"id":"e992e3b4270cd21a","repo":"dotnet/wpf","slug":"sr-enumerator-collectionchanged-vectorcollection","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/Media/Generated/VectorCollection.cs","lineNumber":817,"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":799,"sourceCodeEnd":835,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Generated/VectorCollection.cs#L799-L835","documentation":"VectorCollection's enumerator stores the collection's _version when created; MoveNext compares versions on each advance. If the collection was modified (Add, Remove, Clear, Insert, Set) after the enumerator was obtained, MoveNext throws InvalidOperationException (Enumerator_CollectionChanged). This is standard fail-fast enumerator invalidation protecting against iterating a mutated list.","triggerScenarios":"Calling MoveNext() (explicitly or via foreach) on a VectorCollection enumerator after any structural modification of the same collection since GetEnumerator() was called.","commonSituations":"Adding/removing vectors inside a foreach over a VectorCollection; modifying the collection from another thread or event handler (e.g. Animation/Render callbacks) while a loop is in progress; calling Clear() then continuing to iterate a stale enumerator.","solutions":["Do not modify the collection inside the foreach; collect pending changes in a temporary list and apply them after the loop.","Iterate over a snapshot: `foreach (var v in vectorCollection.ToArray())` so mutation of the original is safe.","If modification is required mid-loop, break out, mutate, then obtain a fresh enumerator via a new foreach.","Synchronize access so no other thread/event mutates the collection during iteration."],"exampleFix":"// before\nforeach (Vector v in vectorCollection) { if (v.Length == 0) vectorCollection.Remove(v); } // throws\n// after\nforeach (Vector v in vectorCollection.ToArray()) { if (v.Length == 0) vectorCollection.Remove(v); }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"var snapshot = vectorCollection.ToArray();\nforeach (var v in snapshot)\n{\n    try { /* mutate vectorCollection if needed */ }\n    catch (InvalidOperationException ex) when (ex.Message.Contains(\"changed\"))\n    {\n        // restart iteration with a fresh enumerator\n    }\n}","preventionTips":["Never mutate a VectorCollection inside foreach over it.","Iterate a snapshot (ToArray/ToList) when mutation is required.","Perform collection mutations and iteration on the same UI thread.","Defer batch changes until after enumeration completes."],"tags":["wpf","invalidoperationexception","enumerator","collection-modified"],"backgroundTag":"collection-was-modified-during-iteration","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"}