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

  1. Call MoveNext() before reading Current — or simply use a foreach loop, which handles this correctly.
  2. Check MoveNext()'s return value before accessing Current inside the loop body.
  3. 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

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


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)