dotnet/wpf · error · InvalidOperationException
SR.Enumerator_ReachedEnd
Error message
SR.Enumerator_ReachedEnd
What it means
Reading Current on a MatchingLanguageEnumerator after MoveNext() returned false, i.e. iteration has passed the last element. The enumerator throws InvalidOperationException because there is no current item to return.
Solutions
- Break out of the loop when MoveNext() returns false before touching Current
- Use foreach, which never reads Current past the end
- Reset or re-acquire the enumerator instead of continuing to advance it
Example fix
// before
while (true) { Process(e.Current); e.MoveNext(); } // throws at end
// after
while (e.MoveNext()) { Process(e.Current); } Defensive patterns
Strategy: try-catch
Validate before calling
bool hasCurrent = e.MoveNext(); // only then read e.Current
Try / catch
try { var v = e.Current; } catch (InvalidOperationException) { /* past end */ } Prevention
- Break loops when MoveNext() returns false
- Use foreach which guarantees Current is valid
When it happens
Trigger: Calling Current after MoveNext() returned false; repeatedly reading Current in a loop that ignores MoveNext's return value; re-reading Current at the end of manual iteration.
Common situations: Manual while(true) loops over GetMatchingLanguages() without breaking on false; enumerators stored across iterations and advanced past the end.
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_NotStarted
- SR.Enumerator_NotStarted
- SR.Enumerator_NotStarted
- SR.Enumerator_ReachedEnd
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/073dedc50946aae3.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Markup/XmlLanguage.cs:523
public void Reset()
{
_current = _start;
_pastEnd = false;
_atStart = true;
_maxCultureDepth = XmlLanguage.MaxCultureDepth;
}
public XmlLanguage Current
{
get
{
if (_atStart)
{
throw new InvalidOperationException(SR.Enumerator_NotStarted);
}
if (_pastEnd)
{
throw new InvalidOperationException(SR.Enumerator_ReachedEnd);
}
return _current;
}
}
public bool MoveNext()
{
if (_atStart)
{
_atStart = false;
return true;
}
else if (_current.IetfLanguageTag.Length == 0)
{
_atStart = false;
_pastEnd = true;
return false;View on GitHub (pinned to 81131a70a4)