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
- Obtain the correct paragraph view for the position (owner paragraph must contain it) before calling GetPositionAtNextLine
- Re-derive the position after edits instead of reusing cached pointers across document changes
- Clamp/verify the position lies within the paragraph's range before the call (compare with the paragraph's start/end pointers)
- 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
- Route vertical navigation through the TextView that owns the position's paragraph
- Discard cached positions after insert/delete operations
- Clamp positions to the paragraph's range before line-relative movement
- Test caret movement across paragraph boundaries
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
- Argument out of range (end not contained in view)
- Argument out of range (start not contained in view)
- ArgumentException.NonNegativeValue (Parameter 'squareScale')
- ArgumentException.PositiveValue (Parameter 'value')
- ArgumentException.PositiveValue (Parameter 'value')
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)