dotnet/wpf · error · ArgumentException
SR.NotInAssociatedTree
Error message
SR.NotInAssociatedTree
What it means
ITextRange.Contains throws ArgumentException when the supplied TextPointer belongs to a different TextContainer than the range itself. Ranges can only reason about positions within their own text tree; cross-tree pointers are meaningless. The message name SR.NotInAssociatedTree conveys the pointer is not in the range's associated tree.
Solutions
- Ensure the TextPointer comes from the same document/container as the range
- Compare within the correct TextSelection of the same RichTextBox
- If cross-document checks are needed, compare textual content or convert positions explicitly rather than passing pointers across trees
Example fix
// before bool has = otherDoc.Selection.Contains(pointerFromDocA); // after bool has = (pointerFromDocA.TextContainer == range.Start.TextContainer) && range.Contains(pointerFromDocA);
Defensive patterns
Strategy: validation
Validate before calling
if (pointer == null || range.Start == null || pointer.TextContainer != range.Start.TextContainer) throw new ArgumentException("pointer from different tree"); Type guard
bool SameTree(ITextRange r, TextPointer p) => r.Start != null && p.TextContainer == r.Start.TextContainer;
Try / catch
try { bool c = range.Contains(pointer); } catch (ArgumentException ex) { /* cross-document pointer */ } Prevention
- Track which document each TextPointer originated from
- Never cache pointers across RichTextBox/FlowDocument instances
When it happens
Trigger: Calling Contains(textPointer) on a TextRange/TextSelection whose Start.TextContainer differs from textPointer.TextContainer — e.g. testing whether a selection contains a pointer from another RichTextBox or FlowDocument.
Common situations: Multiple RichTextBox/FlowDocument instances in one window; comparing caret positions across documents after a paste or drag-drop between editors; caching TextPointers from one document and testing against a range in another.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- SR.BadDistance
- SR.BadTextPositionOrder
- SR.Format(SR.MaxLengthExceedsBufferSize, count…
- SR.Format(SR.NegativeValue, "count")
- SR.Format(SR.NegativeValue, "startIndex")
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/0368dd5321c2af67.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/TextRangeBase.cs:65
//......................................................
//
// Selection Building
//
//......................................................
/// <summary>
/// </summary>
// need to accound for position.LogicalDirection. -- see TextSegment.Contains implementation
internal static bool Contains(ITextRange thisRange, ITextPointer textPointer)
{
NormalizeRange(thisRange);
ArgumentNullException.ThrowIfNull(textPointer);
if (textPointer.TextContainer != thisRange.Start.TextContainer)
{
throw new ArgumentException(SR.NotInAssociatedTree, nameof(textPointer));
}
// Correct position normalization on range boundary so that
// our test would not depend on what side of formatting tags
// pointer is located.
if (textPointer.CompareTo(thisRange.Start) < 0)
{
textPointer = textPointer.GetFormatNormalizedPosition(LogicalDirection.Forward);
}
else if (textPointer.CompareTo(thisRange.End) > 0)
{
textPointer = textPointer.GetFormatNormalizedPosition(LogicalDirection.Backward);
}
// Check if at least one segment contains this position.
for (int i = 0; i < thisRange._TextSegments.Count; i++)
{
if (thisRange._TextSegments[i].Contains(textPointer))View on GitHub (pinned to 81131a70a4)