dotnet/wpf · error · ArgumentException

SR.TextElement_UnmatchedEndPointer

Error message

SR.TextElement_UnmatchedEndPointer

What it means

TextElement.Reposition validates that its start/end TextPointer arguments are paired. Passing an end pointer while start is null means the end cannot be verified against a matching start, so it throws ArgumentException with TextElement_UnmatchedEndPointer. The start/end pair must be supplied together or not at all.

Solutions

  1. Pass both start and end pointers together, or pass neither.
  2. If only one boundary is known, compute the matching boundary before calling.
  3. Guard inputs: verify start/end are both null or both non-null before the call.

Example fix

// before
element.Reposition(null, endPointer);
// after
if (startPointer != null && endPointer != null)
    element.Reposition(startPointer, endPointer);
else
    element.Reposition(null, null);
Defensive patterns

Strategy: validation

Validate before calling

bool paired = (start == null && end == null) || (start != null && end != null);
if (!paired) throw new ArgumentException("start and end must be supplied together");

Try / catch

try { element.Reposition(start, end); }
catch (ArgumentException) { /* repair the pointer pair and retry once */ }

Prevention

When it happens

Trigger: Calling Reposition (directly or via InsertElementClone, SplitElement, MergeParagraphs, PasteMergeableTextFragment, undo units) with start=null and a non-null end pointer.

Common situations: Programmatic construction of text elements in FlowDocument editing where only one boundary is computed; copy/paste code passing partial ranges.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextElement.cs:100

        /// <remarks>
        /// This method extracts the TextElement from its current position,
        /// leaving behind any contained content, before inserting the TextElement
        /// at a new location.
        ///
        /// If start is null, end must also be null, and the TextElement will
        /// not be inserted into a new document.
        /// </remarks>
        internal void Reposition(TextPointer start, TextPointer end)
        {
            TextContainer tree;

            if (start != null)
            {
                ValidationHelper.VerifyPositionPair(start, end);
            }
            else if (end != null)
            {
                throw new ArgumentException(SR.TextElement_UnmatchedEndPointer);
            }

            if (start != null)
            {
                // start/end must be equally scoped.  But we want to discount
                // this TextElement when considering scoping -- it will be
                // extracted before the final insert.

                SplayTreeNode startNode = start.GetScopingNode();
                SplayTreeNode endNode = end.GetScopingNode();

                if (startNode == _textElementNode)
                {
                    startNode = _textElementNode.GetContainingNode();
                }
                if (endNode == _textElementNode)
                {
                    endNode = _textElementNode.GetContainingNode();

View on GitHub (pinned to 81131a70a4)