{"record":{"id":"2678dc56be2d0c31","repo":"dotnet/wpf","slug":"sr-undonoopenunit-undomanager","errorCode":null,"errorMessage":"SR.UndoNoOpenUnit","messagePattern":"SR\\.UndoNoOpenUnit","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/documents/UndoManager.cs","lineNumber":322,"sourceCode":"        /// Thrown if:\n        ///     UndoManager is disabled\n        ///     no undo unit is currently open\n        /// </exception>\n        /// <exception cref=\"ArgumentNullException\">\n        /// Thrown if unit is null\n        /// </exception>\n        internal void Close(IParentUndoUnit unit, UndoCloseAction closeAction)\n        {\n            if (!IsEnabled)\n            {\n                throw new InvalidOperationException(SR.UndoServiceDisabled);\n            }\n\n            ArgumentNullException.ThrowIfNull(unit);\n\n            if (OpenedUnit == null)\n            {\n                throw new InvalidOperationException(SR.UndoNoOpenUnit);\n            }\n\n            // find the parent of the given unit\n            if (OpenedUnit != unit)\n            {\n                IParentUndoUnit closeParent;\n\n                closeParent = OpenedUnit;\n\n                while (closeParent.OpenedUnit != null && closeParent.OpenedUnit != unit)\n                {\n                    closeParent = closeParent.OpenedUnit;\n                }\n\n                if (closeParent.OpenedUnit == null)\n                {\n                    throw new ArgumentException(SR.UndoUnitNotFound, nameof(unit));\n                }","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/documents/UndoManager.cs#L304-L340","documentation":"InvalidOperationException from UndoManager.Close: there is no currently open parent undo unit to close — Close was called without a matching prior Open (or the unit was already closed), so the close operation has no target.","triggerScenarios":"Calling Close without a matching Open, calling Close twice for the same unit, or Close after an exception path already closed the unit.","commonSituations":"Double-close from both a text-change handler and a finally block, or Close in cleanup code when Open was skipped because undo was disabled.","solutions":["Check UndoManager.OpenedUnit != null before calling Close","Ensure each Open has exactly one Close (use try/finally with a closed flag)","Skip Close when Open was never reached or failed"],"exampleFix":"// before\nundoManager.Open(unit);\n...\nundoManager.Close(unit, UndoCloseAction.Commit);\nundoManager.Close(unit, UndoCloseAction.Commit); // throws\n// after\nundoManager.Open(unit);\n...\nif (undoManager.OpenedUnit != null)\n{\n    undoManager.Close(unit, UndoCloseAction.Commit);\n}","handlingStrategy":"validation","validationCode":"if (undoManager.OpenedUnit == null) { /* nothing open: skip Close */ }","typeGuard":null,"tryCatchPattern":"try { undoManager.Close(unit, UndoCloseAction.Commit); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"no open unit\")) { /* nothing to close: ignore */ }","preventionTips":["Track open/close pairing with a flag","Close exactly once per Open","Skip Close when Open was skipped or failed"],"tags":["wpf","undo","invalid-operation"],"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-22T01:17:13.364Z"}