egametang/ET · error · InvalidOperationException
InvalidOperation_EnumOpCantHappen
Error message
InvalidOperation_EnumOpCantHappen
What it means
Thrown by the non-generic IEnumerator.Current getter when _current is null, i.e. the enumerator has not started (MoveNext never called) or has already finished. Accessing Current outside a valid MoveNext-true window is undefined, so the library rejects it. Surfaces as InvalidOperationException (InvalidOperation_EnumOpCantHappen).
Source
Thrown at Packages/cn.etetet.core/Scripts/Core/Share/Collection/SortedSet.cs:2115
public T Current
{
get
{
if (_current != null)
{
return _current.Item;
}
return default(T)!; // Should only happen when accessing Current is undefined behavior
}
}
object IEnumerator.Current
{
get
{
if (_current == null)
{
throw new InvalidOperationException(SR.InvalidOperation_EnumOpCantHappen);
}
return _current.Item;
}
}
internal bool NotStartedOrEnded => _current == null;
internal void Reset()
{
if (_version != _tree.version)
{
throw new InvalidOperationException(SR.InvalidOperation_EnumFailedVersion);
}
_stack.Clear();
Initialize();
}
View on GitHub (pinned to 5cab01f7a8)
Solutions
- Always guard Current with a successful MoveNext: if (e.MoveNext()) x = e.Current;
- Prefer the generic GetEnumerator()/foreach pattern, which never reads Current prematurely.
- Check NotStartedOrEnded (_current == null) before accessing Current in manual code.
Example fix
// before var e = set.GetEnumerator(); var first = e.Current; // throws // after var e = set.GetEnumerator(); object first = e.MoveNext() ? e.Current : null;
Defensive patterns
Strategy: validation
Validate before calling
// Guard Current with a successful MoveNext. var e = set.GetEnumerator(); T first = e.MoveNext() ? e.Current : default;
Prevention
- Prefer foreach over manual MoveNext/Current loops.
- Check NotStartedOrEnded before reading Current in manual code.
- Never read Current after MoveNext returns false.
When it happens
Trigger: Reading IEnumerator.Current before the first MoveNext; reading Current after MoveNext returned false; calling Reset then Current without MoveNext again.
Common situations: Manual enumerator driving (while (e.MoveNext()) ... e.Current) with a logic bug; using the non-generic IEnumerator via LINQ/Reflection that touches Current eagerly; copy-paste of enumerator loops missing the MoveNext guard.
Related errors
- InvalidOperation_EnumFailedVersion
- ArgumentOutOfRange_Index
- Arg_ArrayPlusOffTooSmall
- Argument_IncompatibleArrayType
- SortedSet_LowerValueGreaterThanUpperValue
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/41bb8f32ea6013d0.
Report an issue: GitHub.