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
- Ensure both pointers come from the same TextContainer; re-acquire from the current document when in doubt.
- Check startPosition.TextContainer == endPosition.TextContainer before building ranges.
- 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
- Build ranges from pointers of one document only
- Invalidate cached pointers on Document change
- Validate start<=end and same container before span APIs
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
- SR.Format(SR.InDifferentTextContainers, "start", "end")
- SR.NotInAssociatedTree
- SR.TextElement_UnmatchedEndPointer
- " }} " element found. Expected fixed page element ( }} ).
- ' ' ContentType is not valid.
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)