{"record":{"id":"f5e646342c3d717c","repo":"dotnet/wpf","slug":"sr-format-sr-badtextpositionorder-start-end","errorCode":null,"errorMessage":"SR.Format(SR.BadTextPositionOrder, \"start\", \"end\")","messagePattern":"SR\\.Format\\(SR\\.BadTextPositionOrder, \"start\", \"end\"\\)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/Span.cs","lineNumber":96,"sourceCode":"        /// </param>\n        /// <param name=\"end\">\n        /// End position of the new Span.\n        /// </param>\n        /// <remarks>\n        /// start and end must both be parented by the same Paragraph, otherwise\n        /// the method will raise an ArgumentException.\n        /// </remarks>\n        public Span(TextPointer start, TextPointer end)\n        {\n            ArgumentNullException.ThrowIfNull(start);\n            ArgumentNullException.ThrowIfNull(end);\n            if (start.TextContainer != end.TextContainer)\n            {\n                throw new ArgumentException(SR.Format(SR.InDifferentTextContainers, \"start\", \"end\"));\n            }\n            if (start.CompareTo(end) > 0)\n            {\n                throw new ArgumentException(SR.Format(SR.BadTextPositionOrder, \"start\", \"end\"));\n            }\n\n            start.TextContainer.BeginChange();\n            try\n            {\n                start = TextRangeEditTables.EnsureInsertionPosition(start);\n                Invariant.Assert(start.Parent is Run);\n                end = TextRangeEditTables.EnsureInsertionPosition(end);\n                Invariant.Assert(end.Parent is Run);\n\n                if (start.Paragraph != end.Paragraph)\n                {\n                    throw new ArgumentException(SR.Format(SR.InDifferentParagraphs, \"start\", \"end\"));\n                }\n\n                // If start or end positions have a Hyperlink ancestor, we cannot split them.\n                Inline nonMergeableAncestor;\n                if ((nonMergeableAncestor = start.GetNonMergeableInlineAncestor()) != null)","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/Span.cs#L78-L114","documentation":"The Span(TextPointer start, TextPointer end) constructor throws ArgumentException with SR.BadTextPositionOrder when start occurs after end in the text container (start.CompareTo(end) > 0). The constructor requires start to be at or before end, and both must already be in the same container (checked just before).","triggerScenarios":"new Span(start, end) where the caller passes the positions in reverse order relative to document flow - e.g. start from a selection end and end from the selection start.","commonSituations":"Using RichTextBox.Selection.Start/End inconsistently; building ranges from user selections where the anchor/focus order is not normalized; converting coordinates or offsets to pointers and getting them swapped.","solutions":["Normalize the two pointers with Min/Max before constructing: var s = start.CompareTo(end) <= 0 ? start : end; ...","Order positions by document offset before calling the constructor.","Guard with start.CompareTo(end) <= 0 and swap or report a clearer error beforehand.","Catch ArgumentException and retry with swapped arguments."],"exampleFix":"// before\nvar span = new Span(pointerA, pointerB);\n// after\nvar (start, end) = pointerA.CompareTo(pointerB) <= 0 ? (pointerA, pointerB) : (pointerB, pointerA);\nvar span = new Span(start, end);","handlingStrategy":"validation","validationCode":"if (start.CompareTo(end) > 0)\n    (start, end) = (end, start); // normalize order before new Span(start, end)","typeGuard":"static (TextPointer, TextPointer) Ordered(TextPointer a, TextPointer b) =>\n    a.CompareTo(b) <= 0 ? (a, b) : (b, a);","tryCatchPattern":"try { span = new Span(start, end); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"order\")) { span = new Span(end, start); }","preventionTips":["Always normalize selection anchor/focus into start/end order","Use selection.Start/End (already ordered) instead of raw pointers","Write a small Ordered() helper and use it everywhere ranges are built"],"tags":["wpf","documents","textpointer","argument-order"],"backgroundTag":"invalid-argument-value","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"}