AvaloniaUI/Avalonia · error · InvalidOperationException
Collection was modified during enumeration.
Error message
Collection was modified during enumeration.
What it means
Centralized ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion throws InvalidOperationException "Collection was modified during enumeration." It is actively used by PooledList<T>: in ForEach (after the loop if the version changed), in Enumerator.MoveNextRare, and in Enumerator.Reset — all triggered when PooledList's _version changed since the enumerator/action captured it. It is the canonical fail-fast for concurrent/recursive mutation during enumeration.
Source
Thrown at src/Avalonia.Base/Collections/Pooled/ThrowHelper.cs:306
throw new InvalidOperationException("Enumeration has not started.");
}
[DoesNotReturn]
internal static void ThrowInvalidOperationException_InvalidOperation_EnumEnded()
{
throw new InvalidOperationException("Enumeration has ended.");
}
[DoesNotReturn]
internal static void ThrowInvalidOperationException_EnumCurrent(int index)
{
throw GetInvalidOperationException_EnumCurrent(index);
}
[DoesNotReturn]
internal static void ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion()
{
throw new InvalidOperationException("Collection was modified during enumeration.");
}
[DoesNotReturn]
internal static void ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen()
{
throw new InvalidOperationException("Invalid enumerator state: enumeration cannot proceed.");
}
[DoesNotReturn]
internal static void ThrowInvalidOperationException_InvalidOperation_NoValue()
{
throw new InvalidOperationException("No value provided.");
}
[DoesNotReturn]
internal static void ThrowInvalidOperationException_ConcurrentOperationsNotSupported()
{
throw new InvalidOperationException("Concurrent operations are not supported.");View on GitHub (pinned to 11c5427268)
Solutions
- Iterate over a snapshot: `foreach (var x in list.ToArray())` or `list.Span` copied out.
- Defer mutations: collect items to add/remove during the loop and apply them after.
- For ForEach, do not mutate the list inside the action; use a plain for loop with index bounds instead.
Example fix
// before
foreach (var item in list)
list.Remove(item); // mutates during enumeration
// after
foreach (var item in list.ToArray())
list.Remove(item); Defensive patterns
Strategy: validation
Validate before calling
foreach (var item in list.ToArray()) // snapshot before mutating
list.Remove(item); Prevention
- Never add/remove/clear/sort a PooledList inside a foreach over it.
- Collect changes during iteration, apply them after.
- For ForEach, do not mutate the list inside the action.
When it happens
Trigger: Adding/removing/clearing/sorting a PooledList while a foreach or manual MoveNext loop over it is live; calling Reset() after mutating; ForEach whose callback mutates the list.
Common situations: Mutating the list inside a foreach body; event reentrancy that adds/removes items; sorting or clearing during iteration; concurrent access from another thread.
Related errors
- Invalid enumerator state: enumeration cannot proceed.
- Collection was modified during enumeration.
- Enumeration was not started. | Enumeration has ended.
- Stack was empty.
- Enumeration has not started.
AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13).
Data as JSON: /api/errors/1b32584fb1ac9094.
Report an issue: GitHub.