dotnet/wpf · error · ArgumentException
SR.Format(SR.InDifferentTextContainers, "start", "end")
Error message
SR.Format(SR.InDifferentTextContainers, "start", "end")
What it means
The Span(TextPointer start, TextPointer end) constructor throws ArgumentException with SR.InDifferentTextContainers ("start" and "end" as parameter names) when the two TextPointers belong to different TextContainers (i.e. different documents/text stores). A Span must cover a range within a single text container, so positions from two different documents cannot define one.
Solutions
- Ensure both TextPointers come from the same document/container before constructing the Span.
- If ranges span documents, compute equivalent positions by offset (e.g. ContentStart.GetOffsetToPosition) in the target document instead.
- Guard with a check that start.TextContainer == end.TextContainer and throw a clearer domain error first.
- Catch ArgumentException and map it to a user-facing 'selection spans documents' message.
Example fix
// before
var span = new Span(doc1Start, doc2End);
// after
if (doc1Start.TextContainer != doc2End.TextContainer)
throw new InvalidOperationException("start and end must belong to the same document.");
var span = new Span(doc1Start, doc1End); Defensive patterns
Strategy: validation
Validate before calling
if (start == null || end == null) throw new ArgumentNullException(start == null ? nameof(start) : nameof(end));
if (start.TextContainer != end.TextContainer)
throw new ArgumentException("start and end must belong to the same TextContainer."); Type guard
static bool SameContainer(TextPointer a, TextPointer b) => a != null && b != null && a.TextContainer == b.TextContainer;
Try / catch
try { span = new Span(start, end); }
catch (ArgumentException ex) { throw new InvalidOperationException("Cannot create a range across two different documents.", ex); } Prevention
- Never mix TextPointers from different FlowDocument/RichTextBox instances
- Invalidate cached pointers when a document is reloaded
- Convert cross-document ranges by text offset, not by reusing pointers
When it happens
Trigger: new Span(startPointer, endPointer) where startPointer and endPointer come from two different FlowDocument/TextEditor/TextContainer instances (start.TextContainer != end.TextContainer).
Common situations: Copying TextPointers between two RichTextBox/FlowDocument instances and assuming they are interchangeable; caching a pointer from a document that was reloaded so the new pointer pairs with an old-document pointer; diffing or copying ranges across documents.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- SR.Format(SR.BadFixedTextPosition, "position")
- SR.Format(SR.BadTextPositionOrder, "start", "end")
- SR.Format(SR.InDifferentParagraphs, "start", "end")
- SR.Format(SR.NotInAssociatedContainer, "position")
- SR.InDifferentTextContainers
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/b2f069ac632e19c1.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/Span.cs:92
/// Creates a new Span instance covering existing content.
/// </summary>
/// <param name="start">
/// Start position of the new Span.
/// </param>
/// <param name="end">
/// End position of the new Span.
/// </param>
/// <remarks>
/// start and end must both be parented by the same Paragraph, otherwise
/// the method will raise an ArgumentException.
/// </remarks>
public Span(TextPointer start, TextPointer end)
{
ArgumentNullException.ThrowIfNull(start);
ArgumentNullException.ThrowIfNull(end);
if (start.TextContainer != end.TextContainer)
{
throw new ArgumentException(SR.Format(SR.InDifferentTextContainers, "start", "end"));
}
if (start.CompareTo(end) > 0)
{
throw new ArgumentException(SR.Format(SR.BadTextPositionOrder, "start", "end"));
}
start.TextContainer.BeginChange();
try
{
start = TextRangeEditTables.EnsureInsertionPosition(start);
Invariant.Assert(start.Parent is Run);
end = TextRangeEditTables.EnsureInsertionPosition(end);
Invariant.Assert(end.Parent is Run);
if (start.Paragraph != end.Paragraph)
{
throw new ArgumentException(SR.Format(SR.InDifferentParagraphs, "start", "end"));
}View on GitHub (pinned to 81131a70a4)