dotnet/wpf · error · InvalidOperationException
SR.Enumerator_ReachedEnd
Error message
SR.Enumerator_ReachedEnd
What it means
This InvalidOperationException is thrown by a CollectionHelper-generated enumerator when Current is accessed after iteration has completed: MoveNext() returned false (internal _index == -2, meaning the enumerator is past the last element). It enforces the IEnumerator contract that Current is undefined once the enumeration is finished.
Solutions
- Capture the last value inside the loop before MoveNext() returns false.
- Call Reset() (or obtain a fresh enumerator) to iterate again from the start.
- Restructure as foreach so Current is only read at valid positions.
Example fix
// before
foreach (var x in collection) { }
var last = e.Current; // throws: reached end
// after
T last = default;
foreach (var x in collection) { last = x; } Defensive patterns
Strategy: try-catch
Validate before calling
while (e.MoveNext())
{
last = e.Current; // save inside the loop, never after
} Type guard
static bool TryLast<T>(IEnumerable<T> seq, out T value) { value = default; using var e = seq.GetEnumerator(); if (!e.MoveNext()) return false; value = e.Current; while (e.MoveNext()) value = e.Current; return true; } Try / catch
try { var item = enumerator.Current; }
catch (InvalidOperationException ex) when (ex.Message.Contains("ReachedEnd") || ex.Message.Contains("end")) { /* enumeration finished; re-enumerate if needed */ } Prevention
- Capture values inside the loop; do not read Current after it ends.
- Get a fresh enumerator instead of reusing an exhausted one.
- Use LINQ (Last(), First()) which manages enumerator state for you.
When it happens
Trigger: Accessing Current after MoveNext() has returned false, or continuing to read Current after a foreach loop over the collection has finished.
Common situations: Keeping a reference to the enumerator and reading Current after the loop; trying to get the 'last' element after the loop ended instead of saving it inside the loop; reusing an exhausted enumerator.
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_NotStarted
- SR.Enumerator_CollectionChanged
- SR.Enumerator_NotStarted
- SR.Enumerator_NotStarted
- SR.Enumerator_NotStarted
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/057ea43b73f4852b.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WpfGfx/codegen/mcg/helpers/CollectionHelper.cs:773
/// off the end of the list. However, the IEnumerable.Current
/// contract requires that we throw exceptions
/// </summary>
public [[type]] Current
{
get
{
if (_index > -1)
{
return _current;
}
else if (_index == -1)
{
throw new InvalidOperationException(SR.Enumerator_NotStarted);
}
else
{
Debug.Assert(_index == -2, "expected -2, got " + _index + "\n");
throw new InvalidOperationException(SR.Enumerator_ReachedEnd);
}
}
}
#endregion
#region Data
private [[type]] _current;
private [[resource.Name]] _list;
private uint _version;
private int _index;
#endregion
}
#endregion
[[/inline]];
}
public static string WriteCollectionMethods(McgResource resource)View on GitHub (pinned to 81131a70a4)