{"record":{"id":"367714a7e467a08c","repo":"dotnet/wpf","slug":"sr-textformatterreentranceprohibited","errorCode":null,"errorMessage":"SR.TextFormatterReentranceProhibited","messagePattern":"SR\\.TextFormatterReentranceProhibited","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/TextFormatting/TextFormatterImp.cs","lineNumber":549,"sourceCode":"            }\n\n            if (c == contextCount)\n            {\n                if (contextCount == 0 || !_multipleContextProhibited)\n                {\n                    //  no free one exists, create a new one\n                    context = new TextFormatterContext();\n                    _contextList.Add(context);\n                }\n                else\n                {\n                    // This instance of TextFormatter only allows a single context, reentering the\n                    // same TextFormatter in this case is not allowed.\n                    //\n                    // This requirement is currently enforced only during optimal break computation.\n                    // Client implementing nesting of optimal break content inside another must create\n                    // a separate TextFormatter instance for each content in different nesting level.\n                    throw new InvalidOperationException(SR.TextFormatterReentranceProhibited);\n                }\n            }\n\n            Debug.Assert(context != null);\n\n            context.Owner = owner;\n            return context;\n        }\n\n\n        /// <summary>\n        /// Create an anti-inversion transform from the inversion flags.\n        /// The result is used to correct glyph bitmap on an output to\n        /// a drawing surface with the specified inversions applied on.\n        /// </summary>\n        internal static MatrixTransform CreateAntiInversionTransform(\n            InvertAxes  inversion,\n            double      paragraphWidth,","sourceCodeStart":531,"sourceCodeEnd":567,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/TextFormatting/TextFormatterImp.cs#L531-L567","documentation":"AcquireContext throws InvalidOperationException(SR.TextFormatterReentranceProhibited) when the same TextFormatter instance is reentered during optimal break computation. A TextFormatter instance allows only one formatting context at a time; nesting optimal-break content requires a separate TextFormatter per nesting level.","triggerScenarios":"Calling TextFormatter.FormatLine again (directly or via TextSource callbacks) on the same TextFormatter instance while an optimal-break formatting operation is already in progress.","commonSituations":"A TextSource implementation that itself calls into the same TextFormatter to build runs; recursive layout where the same shared TextFormatter singleton is used at multiple nesting levels of optimal-break content.","solutions":["Create a new TextFormatter instance for each nesting level of optimal break content","Use TextFormatter.Create() inside your TextSource callbacks instead of the shared instance","Restructure the TextSource so it does not reenter FormatLine during formatting"],"exampleFix":"// before\nclass MySource : TextSource {\n    TextFormatter _fmt = TextFormatter.Create(); // shared\n    public override TextRun GetTextRun(int i) { _fmt.FormatLine(...); } // reentrancy\n}\n// after\nclass MySource : TextSource {\n    public override TextRun GetTextRun(int i) {\n        using (var inner = TextFormatter.Create()) { /* format nested content */ }\n    }\n}","handlingStrategy":"validation","validationCode":"if (_formattingInProgress && ReferenceEquals(currentFormatter, this)) throw new InvalidOperationException(\"Reentrancy detected; use a new TextFormatter per nesting level\");","typeGuard":null,"tryCatchPattern":"try { formatter.FormatLine(...); } catch (InvalidOperationException) { var nested = TextFormatter.Create(); /* retry with nested formatter */ }","preventionTips":["Create a separate TextFormatter instance for each nesting level","Never share one TextFormatter across reentrant TextSource callbacks"],"tags":["wpf","text-formatting","reentrancy","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"}