dotnet/wpf · error · ArgumentException
SR.BadTextPositionOrder
Error message
SR.BadTextPositionOrder
What it means
ValidationHelper.VerifyPositionPair throws ArgumentException(SR.BadTextPositionOrder) when a start TextPointer compares greater than an end TextPointer. The library requires all start/end position pairs to be ordered so that start <= end; passing a reversed pair would break TextRange/TextSegment invariants. This is a pre-condition check on the public text-position API surface.
Solutions
- Swap the arguments so the earlier TextPointer is passed as startPosition.
- Call startPosition.CompareTo(endPosition) before invoking and swap if > 0.
- Verify both pointers come from the same TextContainer and represent the intended logical order.
Example fix
// before
new TextRange(endPointer, startPointer);
// after
if (startPointer.CompareTo(endPointer) > 0) { var t = startPointer; startPointer = endPointer; endPointer = t; }
new TextRange(startPointer, endPointer); Defensive patterns
Strategy: validation
Validate before calling
if (start == null || end == null) throw new ArgumentNullException(nameof(start)); if (start.CompareTo(end) > 0) (start, end) = (end, start);
Try / catch
try { ... } catch (ArgumentException ex) { /* handle reversed/rejected positions */ } Prevention
- Always normalize start/end with CompareTo before building ranges
- Derive ranges from selections using Selection.Start/End which are already ordered
When it happens
Trigger: Calling any API that takes (startPosition, endPosition) where startPosition.TextContainer == endPosition.TextContainer but startPosition.CompareTo(endPosition) > 0 — e.g. constructing a TextRange or selecting a range with the later position passed as 'start'.
Common situations: Constructing ranges from user-selection data where start/end were swapped; computing positions asynchronously and passing them back in reverse order; copying positions from two different selections.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- SR.BadDistance
- SR.Format(SR.MaxLengthExceedsBufferSize, count…
- SR.Format(SR.NegativeValue, "count")
- SR.Format(SR.NegativeValue, "startIndex")
- SR.Format(SR.StartIndexExceedsBufferSize, startIndex…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/326ad88dda4f4259.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/ValidationHelper.cs:63
}
}
// Verifies two positions are safe to use as a logical text span.
//
// Throws ArgumentNullException if startPosition == null || endPosition == null
// ArgumentException if startPosition.TextContainer != endPosition.TextContainer or
// startPosition > endPosition
internal static void VerifyPositionPair(ITextPointer startPosition, ITextPointer endPosition)
{
ArgumentNullException.ThrowIfNull(startPosition);
ArgumentNullException.ThrowIfNull(endPosition);
if (startPosition.TextContainer != endPosition.TextContainer)
{
throw new ArgumentException(SR.Format(SR.InDifferentTextContainers, "startPosition", "endPosition"));
}
if (startPosition.CompareTo(endPosition) > 0)
{
throw new ArgumentException(SR.Format(SR.BadTextPositionOrder, "startPosition", "endPosition"));
}
}
// Throws an ArgumentException if direction is not a valid enum.
internal static void VerifyDirection(LogicalDirection direction, string argumentName)
{
if (direction != LogicalDirection.Forward &&
direction != LogicalDirection.Backward)
{
throw new InvalidEnumArgumentException(argumentName, (int)direction, typeof(LogicalDirection));
}
}
// Throws an ArgumentException if edge is not a valid enum.
internal static void VerifyElementEdge(ElementEdge edge, string param)
{
if (edge != ElementEdge.BeforeStart &&
edge != ElementEdge.AfterStart &&View on GitHub (pinned to 81131a70a4)