dotnet/wpf · error · InvalidOperationException
SR.EnumeratorNotStarted
Error message
SR.EnumeratorNotStarted
What it means
Grid's child enumerator's Current property throws InvalidOperationException (SR.EnumeratorNotStarted) when Current is read before the first MoveNext() call (_currentEnumerator == -1). This mirrors the documented IEnumerator.Current contract: accessing Current before enumeration starts is invalid.
Solutions
- Call MoveNext() before reading Current — or simply use a foreach loop, which handles this correctly.
- Check MoveNext()'s return value before accessing Current inside the loop body.
- Reset/initialize the enumerator if reusing it rather than reading Current on a fresh instance.
Example fix
// before
var e = grid.Children.GetEnumerator();
var first = e.Current; // InvalidOperationException
// after
var e = grid.Children.GetEnumerator();
while (e.MoveNext())
{
var child = e.Current;
} Defensive patterns
Strategy: validation
Validate before calling
var e = grid.Children.GetEnumerator(); bool started = e.MoveNext();
Type guard
bool CanReadCurrent(IEnumerator e) => e.MoveNext(); // true means Current is now valid
Try / catch
try { var cur = e.Current; }
catch (InvalidOperationException) { /* Current read before MoveNext; start the enumeration */ } Prevention
- Prefer foreach over manual enumerators
- Always call MoveNext before reading Current
- Check MoveNext's return value before use
When it happens
Trigger: Reading foreach-free enumerator.Current immediately after GetEnumerator() without a prior MoveNext(); manually driving IEnumerator over Grid children and dereferencing Current first.
Common situations: Hand-written enumeration loops over Grid/UIElementCollection where Current is read before MoveNext; refactored foreach loops converted to explicit enumerator calls; LINQ or custom iterators misusing the 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.EnumeratorReachedEnd
- InvalidOperationException
- SR.Enumerator_CollectionChanged
- SR.Enumerator_NotStarted
- SR.Enumerator_NotStarted
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/0b74387b7f90426b.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/Grid.cs:3971
_enumerator2Index++;
return (true);
}
break;
}
}
_currentEnumerator++;
}
return (false);
}
public Object Current
{
get
{
if (_currentEnumerator == -1)
{
// IEnumerator.Current is documented to throw this exception
throw new InvalidOperationException(SR.EnumeratorNotStarted);
}
if (_currentEnumerator >= 3)
{
// IEnumerator.Current is documented to throw this exception
throw new InvalidOperationException(SR.EnumeratorReachedEnd);
}
// assert below is not true anymore since UIElementCollection allowes for null children
//Debug.Assert(_currentChild != null);
return (_currentChild);
}
}
public void Reset()
{
_currentEnumerator = -1;
_currentChild = null;
_enumerator0.Reset();View on GitHub (pinned to 81131a70a4)