dotnet/wpf · error · InvalidOperationException

throw new…

Error message

throw new InvalidOperationException(SR.EnumeratorReachedEnd);

What it means

The enumerator's Current getter throws InvalidOperationException(SR.EnumeratorReachedEnd) when _done is true, i.e. enumeration has passed the last element. Reading Current after MoveNext returned false violates the IEnumerator/ICollectionView contract, so WPF throws instead of returning stale data.

Solutions

  1. Only read Current immediately after a MoveNext() call that returned true.
  2. Check IsCurrentAfterLast (or _done via a valid loop condition) before accessing CurrentItem.
  3. Re-obtain the enumerator or reset currency with MoveCurrentToFirst after the view changes.

Example fix

// before
do
{
    Process(enumerator.Current); // reads past the end
} while (enumerator.MoveNext());

// after
while (enumerator.MoveNext())
{
    Process(enumerator.Current);
}
Defensive patterns

Strategy: validation

Validate before calling

if (view.IsCurrentAfterLast)
    return;
var current = view.CurrentItem;

Type guard

static bool CanReadCurrent(IEnumerator it) => !IsDone(it);

Try / catch

try { var current = it.Current; }
catch (InvalidOperationException) { /* enumerator exhausted; stop iterating */ }

Prevention

When it happens

Trigger: Continuing to read Current after MoveNext() has returned false, or accessing CurrentItem while the view's currency is positioned after the last element (IsCurrentAfterLast).

Common situations: do/while loops that read Current one time too many; retaining an enumerator across collection changes and reading Current after the view was exhausted or reset.

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/69bf06a8af5cc009. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Data/CompositeCollectionView.cs:1559

                }
                return isCurrentInView;
            }

            public object Current
            {
                get
                {
                    // the spec for ICollectionView.CurrentItem says:
                    // InvalidOperationException: The enumerator is positioned before the first element of the collection or after the last element.
                    if (_index < 0)
                    {
                        // ICollectionView.CurrentItem is documented to throw this exception
                        throw new InvalidOperationException(SR.EnumeratorNotStarted);
                    }
                    if (_done)
                    {
                        // ICollectionView.CurrentItem is documented to throw this exception
                        throw new InvalidOperationException(SR.EnumeratorReachedEnd);
                    }

                    return _current;
                }
            }

            public void Reset()
            {
                CheckVersion();
                _index = -1;
                _current = null;
                DisposeContainerEnumerator();
                _done = false;
            }

            public void Dispose()
            {
                DisposeContainerEnumerator();

View on GitHub (pinned to 81131a70a4)