dotnet/wpf · error · ArgumentException

SR.BadDistance

Error message

SR.BadDistance

What it means

This is the TextPointer(TextContainer, int) constructor validating the symbol offset. The offset must lie strictly between 1 and InternalSymbolCount - 1 (i.e. within the document's actual content, excluding boundary symbols). Offsets outside that range throw ArgumentException(SR.BadDistance).

Solutions

  1. Validate the offset against textContainer.SymbolCount (1 <= offset <= SymbolCount-1) before constructing the TextPointer.
  2. Prefer persistent TextPointer instances or manual movers over stored raw offsets so positions track edits.
  3. Re-clamp the offset to the current document length before use.

Example fix

// before
var tp = new TextPointer(container, savedOffset);
// after
int offset = Math.Max(1, Math.Min(savedOffset, container.SymbolCount - 1));
var tp = new TextPointer(container, offset);
Defensive patterns

Strategy: validation

Validate before calling

bool IsValidOffset(TextContainer c, int offset) => offset >= 1 && offset <= c.SymbolCount - 1;
if (!IsValidOffset(container, offset)) offset = Math.Max(1, Math.Min(offset, container.SymbolCount - 1));

Try / catch

try { tp = new TextPointer(container, offset); }
catch (ArgumentException) { tp = new TextPointer(container, Math.Max(1, container.SymbolCount - 1)); }

Prevention

When it happens

Trigger: Constructing a TextPointer with offset < 1, or an offset greater than or equal to the container's internal symbol count — typically an offset captured before text was deleted, or offset computed from a different/older tree.

Common situations: Storing a character offset and later creating a TextPointer after the document changed (text removed shrinks symbol count); using raw offsets from serialization against a freshly loaded document; off-by-one using count instead of count-1.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextPointer.cs:289

        {
            InitializeOffset(position, 0, direction);
        }

        // Creates a new TextPointer instance.
        internal TextPointer(TextPointer position, int offset, LogicalDirection direction)
        {
            InitializeOffset(position, offset, direction);
        }

        // Creates a new TextPointer instance.
        internal TextPointer(TextContainer textContainer, int offset, LogicalDirection direction)
        {
            SplayTreeNode node;
            ElementEdge edge;

            if (offset < 1 || offset > textContainer.InternalSymbolCount - 1)
            {
                throw new ArgumentException(SR.BadDistance);
            }

            textContainer.GetNodeAndEdgeAtOffset(offset, out node, out edge);

            Initialize(textContainer, (TextTreeNode)node, edge, direction, textContainer.PositionGeneration, false, false, textContainer.LayoutGeneration);
        }

        // Creates a new TextPointer instance.
        internal TextPointer(TextContainer tree, TextTreeNode node, ElementEdge edge)
        {
            Initialize(tree, node, edge, LogicalDirection.Forward, tree.PositionGeneration, false, false, tree.LayoutGeneration);
        }

        // Creates a new TextPointer instance.
        internal TextPointer(TextContainer tree, TextTreeNode node, ElementEdge edge, LogicalDirection direction)
        {
            Initialize(tree, node, edge, direction, tree.PositionGeneration, false, false, tree.LayoutGeneration);
        }

View on GitHub (pinned to 81131a70a4)