dotnet/wpf · error · InvalidOperationException

SR.Enumerator_NotStarted

Error message

SR.Enumerator_NotStarted

What it means

PathSegmentCollection's Enumerator.Current throws Enumerator_NotStarted (InvalidOperationException) when Current is accessed before the first MoveNext call. The enumerator's index is still -1 (before the first element), so there is no valid current item.

Solutions

  1. Call MoveNext() and check it returned true before reading Current.
  2. Use foreach, which handles the MoveNext contract automatically.
  3. Initialize/enumerate the iterator before exposing Current to other code.
  4. Guard reads of Current with a check that at least one MoveNext succeeded.

Example fix

// before
var e = segments.GetEnumerator();
var first = e.Current; // throws
// after
var e = segments.GetEnumerator();
if (e.MoveNext()) { var first = e.Current; }
Defensive patterns

Strategy: validation

Validate before calling

if (!e.MoveNext()) return; // no elements; only read Current after MoveNext()==true

Try / catch

try { var cur = e.Current; }
catch (InvalidOperationException) { /* Current accessed before start */ }

Prevention

When it happens

Trigger: Reading the Enumerator.Current property immediately after GetEnumerator() without calling MoveNext() first.

Common situations: Manual enumerator code that forgets the initial MoveNext, or UI/update logic that reads Current outside a proper iteration loop.

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/1a9552293cb405e3. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Generated/PathSegmentCollection.cs:849

            /// <summary>
            /// Current element
            ///
            /// The behavior of IEnumerable&lt;T>.Current is undefined
            /// before the first MoveNext and after we have walked
            /// off the end of the list. However, the IEnumerable.Current
            /// contract requires that we throw exceptions
            /// </summary>
            public PathSegment 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 PathSegment _current;
            private PathSegmentCollection _list;
            private uint _version;
            private int _index;
            #endregion
        }

View on GitHub (pinned to 81131a70a4)