{"record":{"id":"02d33215402bfe88","repo":"dotnet/wpf","slug":"sr-textrangeedit-invalidstructuralpropertyapply-property","errorCode":null,"errorMessage":"SR.TextRangeEdit_InvalidStructuralPropertyApply (property, nonMergeableAncestor)","messagePattern":"SR\\.TextRangeEdit_InvalidStructuralPropertyApply \\(property, nonMergeableAncestor\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextRangeEdit.cs","lineNumber":2286,"sourceCode":"                    nonMergeableAncestor = parent;\n                    commonAncestor = parent;\n                    break;\n                }\n            }\n\n            // Try to reach the start non-mergeable or original commonAncestor from end.\n            for (parent = (Inline)end.Parent; parent != commonAncestor; parent = (Inline)parent.Parent)\n            {\n                if (!TextSchema.IsMergeableInline(parent.GetType()))\n                {\n                    nonMergeableAncestor = parent;\n                    break;\n                }\n            }\n\n            if (property != null && parent != commonAncestor)\n            {\n                throw new InvalidOperationException(SR.Format(SR.TextRangeEdit_InvalidStructuralPropertyApply, property, nonMergeableAncestor));\n            }\n\n            return (parent == commonAncestor);\n        }\n\n        #endregion Private Methods\n\n        #region Private Types\n        /// <summary>\n        /// This class imposes value ranges, considered valid by editing code, for Dependency properties of type double.\n        /// In other words this class defines value range policies for DPs of type double, in editing context.\n        /// </summary>\n        internal static class DoublePropertyBounds\n        {\n            /// <summary>\n            /// Validates the value and if it's in permitable range then the <paramref name=\"value\"/> is returned.\n            /// Oterwise closest bound(lower/upper) of the range is returned.\n            /// </summary>","sourceCodeStart":2268,"sourceCodeEnd":2304,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextRangeEdit.cs#L2268-L2304","documentation":"TextRangeEdit throws InvalidOperationException when applying a structural (mergeable) formatting property would require splitting through a non-mergeable ancestor element. During ApplyPropertyToTextVirtual the edit engine walks up to find a common ancestor; if property != null and the parent chain diverges through an element that cannot be merged (nonMergeableAncestor), the structural apply is invalid. This is an internal invariant violation surfaced to public ApplyPropertyValue paths.","triggerScenarios":"Applying a paragraph-level structural property (e.g. FlowDirection, TextAlignment) to a selection spanning multiple block elements whose ancestors cannot be merged — e.g. selection crossing TableCell boundaries or nested lists with differing structure.","commonSituations":"Selections spanning table cells, list items, or floated figures; programmatic formatting of whole-document content with mixed structure; applying paragraph properties via TextSelection.ApplyPropertyValue over heterogeneous content.","solutions":["Apply the property per logical block (iterate Blocks and set on each Paragraph) instead of over the whole range","Constrain the selection so it does not cross non-mergeable structural boundaries (table cells, sections)","Use direct property assignment on the TextElement rather than range ApplyPropertyValue for structural properties"],"exampleFix":"// before\nselection.ApplyPropertyValue(Block.TextAlignmentProperty, TextAlignment.Center);\n// after\nforeach (Paragraph p in GetSelectedParagraphs(selection))\n    p.TextAlignment = TextAlignment.Center;","handlingStrategy":"try-catch","validationCode":"bool crossesCells = /* determine via selection start/end ancestor checks */ false;\nif (crossesCells) ApplyPerBlockInstead();","typeGuard":null,"tryCatchPattern":"try { selection.ApplyPropertyValue(prop, value); } catch (InvalidOperationException ex) { /* structural apply across non-mergeable ancestors — apply per block */ }","preventionTips":["Avoid applying structural/paragraph properties to selections spanning tables, lists, or floats","Iterate logical blocks and set properties element-by-element","Test formatting code against heterogeneous document content"],"tags":["wpf","internal","text-editing"],"backgroundTag":"internal-invariant-violation","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"}