{"record":{"id":"988f684fd5ec507b","repo":"dotnet/wpf","slug":"sr-undounitnotontopofstack","errorCode":null,"errorMessage":"SR.UndoUnitNotOnTopOfStack","messagePattern":"SR\\.UndoUnitNotOnTopOfStack","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/documents/UndoManager.cs","lineNumber":256,"sourceCode":"            {\n                throw new InvalidOperationException(SR.UndoServiceDisabled);\n            }\n\n            ArgumentNullException.ThrowIfNull(unit);\n\n            if (OpenedUnit != null)\n            {\n                throw new InvalidOperationException(SR.UndoUnitAlreadyOpen);\n            }\n\n            switch (State)\n            {\n                case UndoState.Normal:\n                case UndoState.Redo:\n                    {\n                        if (UndoCount == 0 || PeekUndoStack() != unit)\n                        {\n                            throw new InvalidOperationException(SR.UndoUnitNotOnTopOfStack);\n                        }\n\n                        break;\n                    }\n\n                case UndoState.Undo:\n                    {\n                        if (RedoStack.Count == 0 || (IParentUndoUnit)RedoStack.Peek() != unit)\n                        {\n                            throw new InvalidOperationException(SR.UndoUnitNotOnTopOfStack);\n                        }\n\n                        break;\n                    }\n\n                case UndoState.Rollback:\n                default:\n                    // should only happen if someone changes the UndoState enum or parameter validation","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/documents/UndoManager.cs#L238-L274","documentation":"InvalidOperationException from UndoManager.Reopen: the unit passed for reopening is not the top unit on the relevant stack (undo stack in Normal/Redo state, redo stack in Undo state), so it cannot be reopened out of order.","triggerScenarios":"Reopen called while State is Normal or Redo and either UndoCount == 0 or PeekUndoStack() != unit.","commonSituations":"Trying to reopen a unit that was already merged/closed into another unit, or reopening after other edits pushed new units onto the undo stack.","solutions":["Only call Reopen with the unit reference that was most recently closed on top of the stack","Verify UndoCount > 0 and the target unit equals the top of the undo stack before reopening","If the unit is buried in the stack, abandon reopening and open a fresh unit instead"],"exampleFix":"// before\nundoManager.Reopen(oldUnit);\n// after\nif (undoManager.UndoCount > 0 && undoManager.PeekUndoStack() == oldUnit)\n{\n    undoManager.Reopen(oldUnit);\n}","handlingStrategy":"validation","validationCode":"bool canReopen = undoManager.UndoCount > 0 && undoManager.PeekUndoStack() == unit;","typeGuard":null,"tryCatchPattern":"try { undoManager.Reopen(unit); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"top of stack\")) { /* open a fresh unit instead */ }","preventionTips":["Only reopen the most recently closed top-of-stack unit","Re-read stack top instead of caching unit references","Open a new unit when the target is buried"],"tags":["wpf","undo","stack-order"],"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"}