dotnet/wpf · error · InvalidOperationException
SR.Enumerator_CollectionChanged
Error message
SR.Enumerator_CollectionChanged
What it means
PathSegmentCollection's Enumerator.MoveNext throws Enumerator_CollectionChanged (InvalidOperationException) when the underlying collection's version changed after the enumerator was created. The enumerator is fail-fast: any Add, Remove, Insert, or Clear between MoveNext calls invalidates it.
Solutions
- Do not modify the collection while enumerating; collect pending changes in a separate list and apply after the loop.
- Iterate over a snapshot: foreach (var s in collection.ToArray()).
- Use a for loop over indices if you must mutate during traversal (and adjust the index accordingly).
- Synchronize access across threads (lock or freeze the collection for cross-thread reads).
Example fix
// before
foreach (var seg in segments) { if (bad(seg)) segments.Remove(seg); }
// after
foreach (var seg in segments.ToArray()) { if (bad(seg)) segments.Remove(seg); } Defensive patterns
Strategy: try-catch
Validate before calling
// snapshot before iterating var snapshot = segments.ToArray();
Try / catch
try { foreach (var s in segments) { Process(s); } }
catch (InvalidOperationException ex) when (ex.Message.Contains("collection")) { /* re-enumerate after mutations settle */ } Prevention
- Never mutate a collection inside foreach; buffer changes and apply after
- Enumerate a snapshot (ToArray) when mutation is possible
- Freeze the collection for read-only cross-thread use
When it happens
Trigger: Modifying the PathSegmentCollection (Add/Remove/Insert/Clear, or changing a segment that raises collection change) while a foreach or explicit Enumerator is iterating it.
Common situations: Mutating path segments inside a foreach loop, a property-changed or rendering callback altering the collection during enumeration, or multi-threaded access where one thread enumerates while another modifies.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- SR.Enumerator_CollectionChanged
- SR.Enumerator_CollectionChanged
- SR.Enumerator_NotStarted
- Cannot pass multidimensional array to the CopyTo method on…
- DoubleKeyFrameCollection
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/4c40dfcb126017a8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Generated/PathSegmentCollection.cs:797
{
_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)