dotnet/wpf · error · InvalidOperationException
SR.EnumeratorInvalidOperation
Error message
SR.EnumeratorInvalidOperation
What it means
ModelTreeEnumerator's IEnumerator.Current getter throws InvalidOperationException('EnumeratorInvalidOperation') when Current is accessed before MoveNext() has positioned the enumerator at the first element. This is part of the documented IEnumerator.Current contract: Current is invalid before begin and after end.
Solutions
- Call MoveNext() (and check it returned true) before reading Current.
- Reset() the enumerator (or get a fresh one via GetEnumerator()) after it is exhausted.
- Replace manual enumeration with foreach or LINQ, which honor the contract.
- Check that content was not cleared, which can leave an enumerator positioned beyond end.
Example fix
// before
var e = items.GetEnumerator();
var first = e.Current; // throws
// after
var e = items.GetEnumerator();
if (e.MoveNext()) { var first = e.Current; } Defensive patterns
Strategy: try-catch
Validate before calling
bool canReadCurrent = enumerator.MoveNext(); // check returned true before reading Current
Try / catch
try { var current = enumerator.Current; }
catch (InvalidOperationException) { /* call MoveNext/Reset first */ } Prevention
- Always gate Current reads on MoveNext() returning true.
- Use foreach or LINQ instead of manual enumerator management.
- Reset or re-acquire the enumerator after exhaustion.
- Never cache enumerator Current values between iterations.
When it happens
Trigger: Accessing the enumerator's Current property immediately after GetEnumerator() without calling MoveNext() first, or after MoveNext() returned false and Reset() was not called.
Common situations: Hand-written foreach replacements, enumerator passed to code that reads Current optimistically, custom LINQ-like helpers that peek at Current, or iterating model content (ItemsControl items / UIElementCollection wrappers) with a stale enumerator after the collection was emptied.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- SR.Enumerator_NotStarted
- SR.Enumerator_NotStarted
- SR.Enumerator_ReachedEnd
- SR.Enumerator_ReachedEnd
- SR.EnumeratorNotStarted
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/71c556fff4416509.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Controls/ModelTreeEnumerator.cs:77
_index = value;
}
}
protected virtual object Current
{
get
{
// Don't VerifyUnchanged(); According to MSDN:
// If the collection is modified between MoveNext and Current,
// Current will return the element that it is set to, even if
// the enumerator is already invalidated.
if (_index == 0)
{
return _content;
}
// Exception is part of the IEnumerator.Current contract when moving beyond begin/end
throw new InvalidOperationException(SR.EnumeratorInvalidOperation);
}
}
protected virtual bool MoveNext()
{
if (_index < 1)
{
// Singular content, can move next to 0 and that's it.
_index++;
if (_index == 0)
{
// don't call VerifyUnchanged if we're returning false anyway.
// This permits users to change the Content after enumerating
// the content (e.g. in the invalidation callback of an inherited
// property). See bug 955389.
VerifyUnchanged();View on GitHub (pinned to 81131a70a4)