dotnet/wpf · error · ArgumentOutOfRangeException

Argument out of range (position does not map to a line)

Error message

Argument out of range (position does not map to a line)

What it means

TextParagraphView.GetPositionAtNextLine throws this ArgumentOutOfRangeException when GetLineFromPosition cannot find a line containing the given position (lineIndex out of the line array bounds). The position belongs to another paragraph or to no laid-out line at all, so line-relative movement is impossible.

Solutions

  1. Obtain the correct paragraph view for the position (owner paragraph must contain it) before calling GetPositionAtNextLine
  2. Re-derive the position after edits instead of reusing cached pointers across document changes
  3. Clamp/verify the position lies within the paragraph's range before the call (compare with the paragraph's start/end pointers)
  4. Catch ArgumentOutOfRangeException and fall back to the paragraph's first/last line position to continue navigation

Example fix

// before
var newPos = paragraphView.GetPositionAtNextLine(stalePosition, suggestedX, lines, out sx, out len);
// after
if (paragraphView.Contains(stalePosition))
{
    var newPos = paragraphView.GetPositionAtNextLine(stalePosition, suggestedX, lines, out sx, out len);
}
else
{
    stalePosition = paragraphView.GetTextPositionFromPoint(new Point(suggestedX, double.NaN), true) ?? stalePosition;
}
Defensive patterns

Strategy: validation

Validate before calling

if (paragraphView.Contains(position))
{
    var newPos = paragraphView.GetPositionAtNextLine(position, suggestedX, count, out sx, out len);
}

Type guard

bool PositionBelongsToView(TextViewBase view, ITextPointer p) => view != null && view.Contains(p);

Try / catch

try { return view.GetPositionAtNextLine(position, suggestedX, count, out sx, out len); }
catch (ArgumentOutOfRangeException) { /* position belongs to another paragraph; hand off to the owner's view */ return null; }

Prevention

When it happens

Trigger: Calling GetPositionAtNextLine with a position whose character offset does not fall within any line of this paragraph's Lines collection — e.g. a pointer from a sibling paragraph, a position beyond the paragraph's last line after a deletion, or a pointer in text that was never laid out.

Common situations: Hit when moving the caret vertically across paragraph boundaries using a single paragraph view, or when cached pointers become stale after text edits shift line boundaries, so the line lookup returns -1 or Count.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/d6763be93f929c60. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/documents/TextParagraphView.cs:155

            // with line movement.
            // Initialy set linesMoved to 0;
            newSuggestedX = suggestedX;
            linesMoved = 0;

            if (count == 0)
            {
                return position;
            }

            ReadOnlyCollection<LineResult> lines = Lines;
            Debug.Assert(lines != null && lines.Count > 0);

            // Get index of the line that contains position.
            int lineIndex = GetLineFromPosition(lines, position);
            if (!(lineIndex >= 0 && lineIndex < lines.Count))
            {
                Debug.Assert(false);
                throw new ArgumentOutOfRangeException(nameof(position));
            }

            // Advance line index by count.
            int oldLineIndex = lineIndex;
            lineIndex = Math.Max(0, lineIndex + count);
            lineIndex = Math.Min(lines.Count - 1, lineIndex);
            linesMoved = lineIndex - oldLineIndex;

            // Get position at suggested X. 
            // If line has not been moved, return the same position. 
            // If suggested X is not provided, use the first position in the line.
            if (linesMoved == 0)
            {
                positionOut = position;
            }
            else if (!double.IsNaN(suggestedX))
            {
                positionOut = lines[lineIndex].GetTextPositionFromDistance(suggestedX);

View on GitHub (pinned to 81131a70a4)