{"record":{"id":"ab3a4c3b79fc5ca2","repo":"stride3d/stride","slug":"the-collection-was-modified-after-the-enumerator-was-created","errorCode":null,"errorMessage":"The collection was modified after the enumerator was created.","messagePattern":"The collection was modified after the enumerator was created\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/core/Stride.Core/Collections/MultiValueSortedDictionary.cs","lineNumber":880,"sourceCode":"        }\n\n        /// <summary>\n        /// Advances the enumerator to the next element of the KoderHack.MultiValueSortedDictionary&lt;TKey,TValue&gt;.\n        /// </summary>\n        /// <returns>\n        /// true if the enumerator was successfully advanced to the next element; false\n        /// if the enumerator has passed the end of the collection.\n        /// </returns>\n        /// <exception cref=\"System.InvalidOperationException\">\n        /// The collection was modified after the enumerator was created.\n        /// </exception>\n        public bool MoveNext()\n        {\n            //if (_Disposed)\n            //    throw new InvalidOperationException(\"The enumerator has already been disposed.\");\n\n            if (_Dictionary._IsModified)\n                throw new InvalidOperationException(\"The collection was modified after the enumerator was created.\");\n\n            if (!_Valid) return false;\n            var key = default(TKey);\n            var value = default(TValue);\n            if (_Enumerator2 == null)\n            {\n                if (_Enumerator1.MoveNext())\n                {\n                    if (_Enumerator1.Current.Value != null)\n                        _Enumerator2 = _Enumerator1.Current.Value.GetEnumerator();\n                }\n                else\n                    _Valid = false;\n            }\n\n            if (!_Valid) return false;\n\n            key = _Enumerator1.Current.Key;","sourceCodeStart":862,"sourceCodeEnd":898,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/core/Stride.Core/Collections/MultiValueSortedDictionary.cs#L862-L898","documentation":"MultiValueSortedDictionary's enumerator tracks whether the underlying dictionary was modified (via the _IsModified flag). MoveNext throws InvalidOperationException('The collection was modified after the enumerator was created.') when any Add/Remove/Clear happened after enumeration started; this enumerator does not support concurrent modification.","triggerScenarios":"Enumerating the dictionary (foreach) and calling Add, Insert, Remove, or Clear on the same dictionary inside or between MoveNext calls; modifying the dictionary from another thread while an enumeration is in progress.","commonSituations":"Removing entries in a foreach loop over the dictionary; building/removing entries while iterating for logging or serialization; shared dictionary mutated by another thread during UI-driven enumeration.","solutions":["Collect the keys/entries to change into a temporary list inside the loop, then apply changes after enumeration","Remove by copying keys first: foreach (var k in keysSnapshot) dict.Remove(k)","Synchronize with a lock so no mutation occurs while enumerating, or take a snapshot (ToArray/ToList) before modifying","Restart the enumeration after the modification if order matters"],"exampleFix":"// before\nforeach (var kv in dict)\n    if (predicate(kv.Value)) dict.Remove(kv.Key); // throws\n// after\nforeach (var key in dict.Keys.ToList())\n    if (predicate(dict[key])) dict.Remove(key);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { foreach (var kv in dict) { /* ... */ } } catch (InvalidOperationException) { /* re-enumerate after mutation */ }","preventionTips":["Never mutate a dictionary during foreach; batch changes into a list and apply after","Take a ToList snapshot of keys/entries before modifying","Use locking for cross-thread access","Obtain a fresh enumerator after modifications"],"tags":["csharp","collections","enumerator","concurrent-modification"],"backgroundTag":"unsupported-operation","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}