stride3d/stride · error · InvalidOperationException

InvalidOperationException

Error message

InvalidOperationException

What it means

IDictionaryEnumerator.Key on SortedDictionary's enumerator throws InvalidOperationException when the enumerator has not been started (MoveNext not yet called) or has already run past the end. There is no current entry to read the key from.

Solutions

  1. Call MoveNext and only access Key when it returns true
  2. Reset the enumerator and re-enumerate if you need another pass
  3. Prefer the generic IEnumerator<KeyValuePair<TKey,TValue>> or foreach instead of IDictionaryEnumerator

Example fix

// before
var e = dict.GetEnumerator();
var key = ((IDictionaryEnumerator)e).Key; // not started
// after
var e = dict.GetEnumerator();
if (e.MoveNext()) { var key = ((IDictionaryEnumerator)e).Key; }
Defensive patterns

Strategy: type-guard

Validate before calling

bool eOk = enumerator is IDictionaryEnumerator de && de.MoveNext(); // position before reading

Type guard

bool CanRead(IDictionaryEnumerator e) { /* track: started and not ended */ return started && !ended; }

Try / catch

try { var key = ((IDictionaryEnumerator)e).Key; } catch (InvalidOperationException) { /* enumerator not positioned; reset and re-enumerate */ e.Reset(); }

Prevention

When it happens

Trigger: Reading .Key from the IDictionaryEnumerator before calling MoveNext, or after MoveNext returned false.

Common situations: Manual non-generic IDictionary enumeration loops that don't check MoveNext's return value or access the key outside the loop body.

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 stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/cadf4a6447c6ba35. Report an issue: GitHub.

Appendix: source

Thrown at sources/core/Stride.Core.Yaml/SortedDictionary.cs:468

                    if (getEnumeratorRetType == DictEntry)
                    {
                        return new DictionaryEntry(Current.Key, Current.Value);
                    }
                    else
                    {
                        return new KeyValuePair<TKey, TValue>(Current.Key, Current.Value);
                    }
                }
            }

            object IDictionaryEnumerator.Key
            {
                get
                {
                    if (NotStartedOrEnded)
                    {
                        throw new InvalidOperationException();
                    }

                    return Current.Key;
                }
            }

            object IDictionaryEnumerator.Value
            {
                get
                {
                    if (NotStartedOrEnded)
                    {
                        throw new InvalidOperationException();
                    }

                    return Current.Value;
                }
            }

View on GitHub (pinned to 96fad776d2)