{"record":{"id":"69bf06a8af5cc009","repo":"dotnet/wpf","slug":"throw-new-invalidoperationexception-sr-enumeratorreachedend","errorCode":null,"errorMessage":"throw new InvalidOperationException(SR.EnumeratorReachedEnd);","messagePattern":"throw new InvalidOperationException\\(SR\\.EnumeratorReachedEnd\\);","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Data/CompositeCollectionView.cs","lineNumber":1559,"sourceCode":"                }\n                return isCurrentInView;\n            }\n\n            public object Current\n            {\n                get\n                {\n                    // the spec for ICollectionView.CurrentItem says:\n                    // InvalidOperationException: The enumerator is positioned before the first element of the collection or after the last element.\n                    if (_index < 0)\n                    {\n                        // ICollectionView.CurrentItem is documented to throw this exception\n                        throw new InvalidOperationException(SR.EnumeratorNotStarted);\n                    }\n                    if (_done)\n                    {\n                        // ICollectionView.CurrentItem is documented to throw this exception\n                        throw new InvalidOperationException(SR.EnumeratorReachedEnd);\n                    }\n\n                    return _current;\n                }\n            }\n\n            public void Reset()\n            {\n                CheckVersion();\n                _index = -1;\n                _current = null;\n                DisposeContainerEnumerator();\n                _done = false;\n            }\n\n            public void Dispose()\n            {\n                DisposeContainerEnumerator();","sourceCodeStart":1541,"sourceCodeEnd":1577,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Data/CompositeCollectionView.cs#L1541-L1577","documentation":"The enumerator's Current getter throws InvalidOperationException(SR.EnumeratorReachedEnd) when _done is true, i.e. enumeration has passed the last element. Reading Current after MoveNext returned false violates the IEnumerator/ICollectionView contract, so WPF throws instead of returning stale data.","triggerScenarios":"Continuing to read Current after MoveNext() has returned false, or accessing CurrentItem while the view's currency is positioned after the last element (IsCurrentAfterLast).","commonSituations":"do/while loops that read Current one time too many; retaining an enumerator across collection changes and reading Current after the view was exhausted or reset.","solutions":["Only read Current immediately after a MoveNext() call that returned true.","Check IsCurrentAfterLast (or _done via a valid loop condition) before accessing CurrentItem.","Re-obtain the enumerator or reset currency with MoveCurrentToFirst after the view changes."],"exampleFix":"// before\ndo\n{\n    Process(enumerator.Current); // reads past the end\n} while (enumerator.MoveNext());\n\n// after\nwhile (enumerator.MoveNext())\n{\n    Process(enumerator.Current);\n}","handlingStrategy":"validation","validationCode":"if (view.IsCurrentAfterLast)\n    return;\nvar current = view.CurrentItem;","typeGuard":"static bool CanReadCurrent(IEnumerator it) => !IsDone(it);","tryCatchPattern":"try { var current = it.Current; }\ncatch (InvalidOperationException) { /* enumerator exhausted; stop iterating */ }","preventionTips":["Use while (enumerator.MoveNext()) loops; never read Current after MoveNext returns false.","Check IsCurrentAfterLast before reading CurrentItem.","Re-acquire enumerators after collection changes rather than reusing exhausted ones."],"tags":["wpf","enumerator","collection-view","current"],"backgroundTag":"invalid-state-transition","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}