dotnet/wpf · error · InvalidOperationException
SR.Enumerator_CollectionChanged
Error message
SR.Enumerator_CollectionChanged
What it means
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.
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.
Example fix
// before
foreach (Vector v in vectorCollection) { if (v.Length == 0) vectorCollection.Remove(v); } // throws
// after
foreach (Vector v in vectorCollection.ToArray()) { if (v.Length == 0) vectorCollection.Remove(v); } Defensive patterns
Strategy: try-catch
Try / catch
var snapshot = vectorCollection.ToArray();
foreach (var v in snapshot)
{
try { /* mutate vectorCollection if needed */ }
catch (InvalidOperationException ex) when (ex.Message.Contains("changed"))
{
// restart iteration with a fresh enumerator
}
} Prevention
- 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.
When it happens
Trigger: Calling MoveNext() (explicitly or via foreach) on a VectorCollection enumerator after any structural modification of the same collection since GetEnumerator() was called.
Common situations: 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.
Related errors
- SR.Enumerator_CollectionChanged
- SR.Enumerator_CollectionChanged
- SR.Enumerator_CollectionChanged
- SR.Enumerator_CollectionChanged
- InvalidOperationException
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/e992e3b4270cd21a.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Generated/VectorCollection.cs:817
{
_list.ReadPreamble();
if (_version == _list._version)
{
if (_index > -2 && _index < _list._collection.Count - 1)
{
_current = _list._collection[++_index];
return true;
}
else
{
_index = -2; // -2 indicates "past the end"
return false;
}
}
else
{
throw new InvalidOperationException(SR.Enumerator_CollectionChanged);
}
}
/// <summary>
/// Sets the enumerator to its initial position, which is before the
/// first element in the collection.
/// </summary>
public void Reset()
{
_list.ReadPreamble();
if (_version == _list._version)
{
_index = -1;
}
else
{
throw new InvalidOperationException(SR.Enumerator_CollectionChanged);View on GitHub (pinned to 81131a70a4)