dotnet/wpf · error · InvalidOperationException
SR.Enumerator_NotStarted
Error message
SR.Enumerator_NotStarted
What it means
TransformCollection.Enumerator.Current throws InvalidOperationException with Enumerator_NotStarted when accessed before the first MoveNext() call. The enumerator's _index is still -1 (positioned before the first element), so there is no valid current item to return.
Solutions
- Always call MoveNext() (and check its true return value) before reading Current.
- Prefer foreach, which manages MoveNext/Current ordering automatically.
- If manual enumeration is required, initialize with `if (e.MoveNext()) { use e.Current; }`.
- Catch InvalidOperationException only as a last-resort guard around Current access.
Example fix
// before
var e = transformCollection.GetEnumerator();
var first = e.Current; // throws: not started
// after
var e = transformCollection.GetEnumerator();
if (e.MoveNext())
{
var first = e.Current;
} Defensive patterns
Strategy: validation
Validate before calling
if (transformCollection.Count > 0 && enumerator.MoveNext())
{
var current = enumerator.Current; // safe
} Type guard
static bool TryGetCurrent(TransformCollection c, out Transform current)
{
using var e = c.GetEnumerator();
if (e.MoveNext()) { current = e.Current; return true; }
current = null; return false;
} Try / catch
try
{
var cur = enumerator.Current;
}
catch (InvalidOperationException)
{
// MoveNext() was never called or enumeration ended; call MoveNext() first
} Prevention
- Always pair Current with a prior successful MoveNext().
- Prefer foreach which enforces MoveNext-before-Current ordering.
- Empty-check Count > 0 before starting manual enumeration.
When it happens
Trigger: Accessing the Current property immediately after GetEnumerator() without calling MoveNext() first; e.g. `var e = collection.GetEnumerator(); var t = e.Current;`.
Common situations: Hand-written enumerator loops that forget the initial MoveNext(); code ported from COM-style iteration; LINQ-free manual enumeration where Current is read inside a condition evaluated before MoveNext.
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.Enumerator_ReachedEnd
- SR.Enumerator_CollectionChanged
- SR.Enumerator_CollectionChanged
- SR.Enumerator_CollectionChanged
- SR.Enumerator_CollectionChanged
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/a9d24468cae3b269.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Generated/TransformCollection.cs:884
/// <summary>
/// Current element
///
/// The behavior of IEnumerable<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 Transform 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 Transform _current;
private TransformCollection _list;
private uint _version;
private int _index;
#endregion
}View on GitHub (pinned to 81131a70a4)