{"record":{"id":"97813f805dd98228","repo":"dotnet/wpf","slug":"sr-undoservicedisabled","errorCode":null,"errorMessage":"SR.UndoServiceDisabled","messagePattern":"SR\\.UndoServiceDisabled","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/documents/UndoManager.cs","lineNumber":190,"sourceCode":"        /// Add the given parent undo unit to the undo manager, making it the OpenedUnit of the\n        /// innermost open parent unit (or the undo manager itself, if no parents are open).\n        /// </summary>\n        /// <param name=\"unit\">\n        /// parent unit to add\n        /// </param>\n        /// <exception cref=\"InvalidOperationException\">\n        /// Thrown if UndoManager is disabled or passed unit is already open.\n        /// </exception>\n        /// <exception cref=\"ArgumentNullException\">\n        /// Thrown if passed unit is null.\n        /// </exception>\n        internal void Open(IParentUndoUnit unit)\n        {\n            IParentUndoUnit deepestOpen;\n\n            if (!IsEnabled)\n            {\n                throw new InvalidOperationException(SR.UndoServiceDisabled);\n            }\n\n            ArgumentNullException.ThrowIfNull(unit);\n\n            deepestOpen = DeepestOpenUnit;\n            if (deepestOpen == unit)\n            {\n                throw new InvalidOperationException(SR.UndoUnitCantBeOpenedTwice);\n            }\n\n            if (deepestOpen == null)\n            {\n                if (unit != LastUnit)\n                {\n                    // Don't want to add the unit again if we're just reopening it\n                    Add(unit as IUndoUnit);\n                    SetLastUnit(unit as IUndoUnit);\n                }","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/documents/UndoManager.cs#L172-L208","documentation":"UndoManager.Open throws this InvalidOperationException when the undo service is disabled (IsEnabled is false) but a caller tries to open a parent undo unit. The undo manager only accepts new open units while enabled, so any Open call after Disable() or during a disabled state fails fast.","triggerScenarios":"Calling Open (directly or via Do, Reopen, OpenCompositionUndoUnit, OpenTypingUndoUnit, or ResizeColumn such as TextBoxBase/TextBox editing) while UndoManager.IsEnabled is false.","commonSituations":"Text editing operations performed after code called UndoManager.Disable() (e.g. IsUndoEnabled=false on a TextBox), or an undo unit callback running while the undo stack was reset/disabled mid-composition.","solutions":["Check UndoManager.IsEnabled before calling Open and skip or re-enable as appropriate","Re-enable undo via UndoManager.Enable() (or set TextBox.IsUndoEnabled=true) before editing operations","Audit code paths that call Disable() and ensure they re-enable before further edits"],"exampleFix":"// before\nundoManager.Open(parentUnit);\n// after\nif (undoManager.IsEnabled)\n{\n    undoManager.Open(parentUnit);\n}","handlingStrategy":"validation","validationCode":"if (!undoManager.IsEnabled) { /* skip or re-enable before Open */ }","typeGuard":null,"tryCatchPattern":"try { undoManager.Open(unit); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"disabled\")) { /* undo disabled: handle gracefully */ }","preventionTips":["Check IsEnabled before any Open/Do call","Keep IsUndoEnabled consistent with edit operations","Never disable undo while an edit batch is in progress"],"tags":["wpf","undo","invalid-operation"],"backgroundTag":"unsupported-operation","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"}