{"record":{"id":"fe16c56079d297be","repo":"dotnet/wpf","slug":"sr-textcontainerchangingreentrancyinvalid","errorCode":null,"errorMessage":"SR.TextContainerChangingReentrancyInvalid","messagePattern":"SR\\.TextContainerChangingReentrancyInvalid","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/documents/FlowDocumentFormatter.cs","lineNumber":63,"sourceCode":"        #region Internal Methods\n\n        /// <summary>\n        /// Formatts content.\n        /// </summary>\n        /// <param name=\"constraint\">Constraint size.</param>\n        internal void Format(Size constraint)\n        {\n            Thickness pageMargin;\n            Size pageSize;\n\n            // Reentrancy check.\n            if (_document.StructuralCache.IsFormattingInProgress)\n            {\n                throw new InvalidOperationException(SR.FlowDocumentFormattingReentrancy);\n            }\n            if (_document.StructuralCache.IsContentChangeInProgress)\n            {\n                throw new InvalidOperationException(SR.TextContainerChangingReentrancyInvalid);\n            }\n\n            // Check if we can continue with formatting without nuking incremental udpate info.\n            if (_document.StructuralCache.IsFormattedOnce)\n            {\n                if (!_lastFormatSuccessful)\n                {\n                    // We cannot resolve update info if last formatting was unsuccessful.\n                    _document.StructuralCache.InvalidateFormatCache(true);\n                }\n                if (!_arrangedAfterFormat && (!_document.StructuralCache.ForceReformat || !_document.StructuralCache.DestroyStructure))\n                {\n                    // Need to clear update info by running arrange process.\n                    // This is necessary, because Format may be called more than once\n                    // before Arrange is called. But PTS is not able to merge update info.\n                    // To protect against loosing incremental changes delta, need\n                    // to arrange the page and create all necessary visuals.\n                    _documentPage.Arrange(_documentPage.ContentSize);","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/documents/FlowDocumentFormatter.cs#L45-L81","documentation":"FlowDocumentFormatter.Format throws InvalidOperationException(SR.TextContainerChangingReentrancyInvalid) when formatting is requested while a content change (edit) is in progress on the document's TextContainer (StructuralCache.IsContentChangeInProgress). Formatting cannot run against a TextContainer that is mid-change; WPF throws to protect container/incremental-format state.","triggerScenarios":"Calling FlowDocumentFormatter.Format (directly or through layout/pagination APIs) from inside a TextContainer change scope — e.g. inside a TextContainer.Change event handler, inside TextPointer insert/remove operations, or from code executed during a document mutation.","commonSituations":"Text-changed event handlers that force layout or paginate synchronously; document edits performed inside layout/pagination notifications; RichTextBox/TextBox event handlers that trigger printing or pagination of the same FlowDocument.","solutions":["Move formatting/pagination requests out of the change-notification scope; defer with Dispatcher.BeginInvoke until the change completes.","Do not call layout/pagination APIs inside TextChanged/ContentChanged handlers on the same FlowDocument.","Batch document edits so change scopes are short and formatting is requested afterward.","Wrap mutations so that any re-layout is triggered once after all edits finish."],"exampleFix":"// before\ndocument.StructuralCache.TextContainer.Changed += (s, e) => {\n    formatter.Format(0); // throws: change in progress\n};\n// after\ndocument.StructuralCache.TextContainer.Changed += (s, e) => {\n    Dispatcher.BeginInvoke(new Action(() => formatter.Format(0)),\n        System.Windows.Threading.DispatcherPriority.Background);\n};","handlingStrategy":"validation","validationCode":"if (_document.StructuralCache.IsContentChangeInProgress)\n    return; // defer formatting until the edit completes","typeGuard":"bool CanFormat(FlowDocument doc) => !doc.StructuralCache.IsContentChangeInProgress && !doc.StructuralCache.IsFormattingInProgress;","tryCatchPattern":"try { formatter.Format(offset); }\ncatch (InvalidOperationException ex) {\n    Dispatcher.BeginInvoke(new Action(() => formatter.Format(offset)), DispatcherPriority.Background);\n}","preventionTips":["Do not trigger layout/pagination inside ContentChanged/TextChanged handlers","Complete edit transactions before requesting formatting","Use a dirty flag and format on the next dispatcher pass","Avoid reentrant document mutations from event handlers"],"tags":["wpf","flowdocument","reentrancy","textcontainer"],"backgroundTag":"unsupported-operation","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"}