dotnet/wpf · error · InvalidOperationException
SR.Enumerator_ReachedEnd
Error message
SR.Enumerator_ReachedEnd
What it means
Point3DCollection's enumerator Current property throws InvalidOperationException(SR.Enumerator_ReachedEnd) when Current is accessed after enumeration completed (MoveNext returned false, _index == -2). Same fail-fast contract as the BCL List<T> enumerator.
Solutions
- Capture the current item in a local variable inside the loop instead of reading Current afterwards
- Call Reset() (on an unmodified collection) before re-reading, or get a fresh enumerator
- Restructure to use foreach with a variable holding the element of interest
Example fix
// before
Point3D last;
foreach (Point3D p in collection) { }
last = ((Point3DCollection.Enumerator)en).Current; // throws
// after
Point3D last = default;
foreach (Point3D p in collection) { last = p; } Defensive patterns
Strategy: type-guard
Validate before calling
bool canRead = lastMoveNextReturnedTrue; // track MoveNext outcome in a variable
Type guard
bool TryGetCurrent(Point3DCollection.Enumerator e, ref bool finished, out Point3D cur) { cur = default; if (finished) return false; cur = e.Current; return true; } Try / catch
try { var cur = e.Current; }
catch (InvalidOperationException) { /* enumerator exhausted; capture items inside the loop instead */ } Prevention
- Store the desired item in a local inside the loop, not via Current afterwards
- Use foreach so Current is never read post-loop
- Reset or re-create the enumerator before another pass
When it happens
Trigger: Accessing e.Current after a foreach or while(MoveNext()) loop finished; reading Current of an exhausted enumerator without Reset().
Common situations: Grabbing 'the last visited item' after loop exit; debugging code that reads Current post-enumeration.
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_ReachedEnd
- Microsoft.Windows.Controls.SR.Format(Microsoft.Windows.Contr…
- Microsoft.Windows.Controls.SR.Format(Microsoft.Windows.Contr…
- Microsoft.Windows.Controls.SR.Ribbon_ContextualTabHeadersSou…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/8c900f4befabf9f8.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media3D/Generated/Point3DCollection.cs:873
/// off the end of the list. However, the IEnumerable.Current
/// contract requires that we throw exceptions
/// </summary>
public Point3D 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 Point3D _current;
private Point3DCollection _list;
private uint _version;
private int _index;
#endregion
}
#endregion
#region Constructors
//------------------------------------------------------View on GitHub (pinned to 81131a70a4)