dotnet/wpf · error · ArgumentException

SR.InDifferentTextContainers

Error message

SR.InDifferentTextContainers

What it means

ValidationHelper.VerifyPositionPair throws ArgumentException(SR.InDifferentTextContainers) when startPosition and endPosition come from different ITextContainers. A text span (start,end) must be defined within one document; WPF validates this up front.

Solutions

  1. Ensure both pointers come from the same TextContainer; re-acquire from the current document when in doubt.
  2. Check startPosition.TextContainer == endPosition.TextContainer before building ranges.
  3. Reset cached pointers whenever the Document property changes (listen to DocumentChanged/Loaded).

Example fix

// before
var range = new TextRange(oldDocStart, newDocEnd); // may throw
// after
if (oldDocStart.TextContainer != newDocEnd.TextContainer)
    oldDocStart = currentDoc.ContentStart;
var range = new TextRange(oldDocStart, newDocEnd);
Defensive patterns

Strategy: type-guard

Validate before calling

bool pairValid = startPosition != null && endPosition != null
    && startPosition.TextContainer == endPosition.TextContainer
    && startPosition.CompareTo(endPosition) <= 0;

Type guard

bool SameContainerOrdered(ITextPointer s, ITextPointer e) => s != null && e != null && s.TextContainer == e.TextContainer && s.CompareTo(e) <= 0;

Try / catch

try { var range = new TextRange(start, end); }
catch (ArgumentException) { start = doc.ContentStart; end = doc.ContentEnd; range = new TextRange(start, end); }

Prevention

When it happens

Trigger: Calling span APIs (TextRange construction, selection setting, VerifyPositionPair) with start/end pointers originating from different documents/containers.

Common situations: Constructing TextRange(start, end) where one pointer was cached from a previous document; selection APIs fed with pointers from a second RichTextBox; copy/paste code mixing source and target pointers.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/ValidationHelper.cs:59

            if (position.TextContainer != container)
            {
                throw new ArgumentException(SR.Format(SR.NotInAssociatedTree, paramName));
            }
        }

        // 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.

View on GitHub (pinned to 81131a70a4)