{"record":{"id":"bc1bc8f2d76e2cd5","repo":"Unity-Technologies/ml-agents","slug":"enumerator-has-reached-the-end-already","errorCode":null,"errorMessage":"Enumerator has reached the end already.","messagePattern":"Enumerator has reached the end already\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"com.unity.ml-agents/Runtime/Actuators/ActionSegment.cs","lineNumber":217,"sourceCode":"\n            public bool MoveNext()\n            {\n                if (m_Current < m_End)\n                {\n                    m_Current++;\n                    return m_Current < m_End;\n                }\n                return false;\n            }\n\n            public T Current\n            {\n                get\n                {\n                    if (m_Current < m_Start)\n                        throw new InvalidOperationException(\"Enumerator not started.\");\n                    if (m_Current >= m_End)\n                        throw new InvalidOperationException(\"Enumerator has reached the end already.\");\n                    return m_Array[m_Current];\n                }\n            }\n\n            object IEnumerator.Current => Current;\n\n            void IEnumerator.Reset()\n            {\n                m_Current = m_Start - 1;\n            }\n\n            public void Dispose()\n            {\n            }\n        }\n    }\n}\n","sourceCodeStart":199,"sourceCodeEnd":235,"githubUrl":"https://github.com/Unity-Technologies/ml-agents/blob/3ecb446f75d1e7400eb404c562dc005d3164cffc/com.unity.ml-agents/Runtime/Actuators/ActionSegment.cs#L199-L235","documentation":"The ActionSegment<T>.Enumerator's Current getter throws InvalidOperationException when m_Current has advanced past m_End, meaning MoveNext() already returned false and the caller keeps reading Current. Standard .NET behavior: enumeration finished but Current accessed again.","triggerScenarios":"Calling Current after MoveNext() returned false — e.g. an unbounded while loop reading Current after exhausting the segment, or reading Current twice past the end.","commonSituations":"Loops that forget to break when MoveNext() returns false; nested foreach misuse; iterating a zero-length segment and unconditionally accessing Current.","solutions":["Stop reading Current once MoveNext() returns false","Guard iteration in a while(e.MoveNext()) loop","Check segment Length > 0 before enumerating"],"exampleFix":"// before\ne.MoveNext();\nvar v = e.Current; // after end\n// after\nwhile (e.MoveNext()) { var v = e.Current; }","handlingStrategy":"try-catch","validationCode":"while (e.MoveNext()) { Use(e.Current); } // never read Current outside a successful MoveNext","typeGuard":null,"tryCatchPattern":"try { var v = e.Current; } catch (InvalidOperationException) { /* enumerator exhausted; stop */ }","preventionTips":["Stop when MoveNext() returns false","Don't read Current after the loop ends","Guard empty segments before enumerating"],"tags":["unity","ml-agents","enumerator","invalid-operation"],"backgroundTag":"enumerator-misuse","analyzedSha":"3ecb446f75d1e7400eb404c562dc005d3164cffc","analyzedAt":"2026-09-02T16:33:12.832Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}