dotnet/wpf · error · ArgumentException
SR.Format(SR.InDifferentParagraphs, "start", "end")
Error message
SR.Format(SR.InDifferentParagraphs, "start", "end")
What it means
The Span(TextPointer start, TextPointer end) constructor throws ArgumentException with SR.InDifferentParagraphs when, after normalizing both positions to insertion positions inside Runs, the positions resolve to different Paragraph elements. A Paragraph-range Span (used for Paragraph construction/scoping) must lie entirely within one paragraph.
Solutions
- Only construct this Span when both positions are inside the same Paragraph (compare start.Paragraph and end.Paragraph).
- Split multi-paragraph ranges into one Span per paragraph and process each separately.
- Use TextRange (which supports cross-paragraph ranges) instead of Span when the range legitimately spans paragraphs.
- Catch ArgumentException and fall back to a TextRange-based implementation.
Example fix
// before
var span = new Span(selection.Start, selection.End); // may cross paragraphs
// after
if (selection.Start.Paragraph != selection.End.Paragraph)
return null; // or handle per paragraph
var span = new Span(selection.Start, selection.End); Defensive patterns
Strategy: validation
Validate before calling
if (start.Paragraph != end.Paragraph)
throw new ArgumentException("Span range must lie within a single paragraph."); Type guard
static bool WithinOneParagraph(TextPointer a, TextPointer b) => a.Paragraph != null && a.Paragraph == b.Paragraph;
Try / catch
try { span = new Span(start, end); }
catch (ArgumentException ex) when (ex.Message.Contains("paragraph")) { return ProcessPerParagraph(start, end); } Prevention
- Check Paragraph equality before constructing paragraph-scoped Spans
- Split multi-paragraph selections per paragraph
- Use TextRange when cross-paragraph ranges are legitimate
When it happens
Trigger: new Span(start, end) where start and end are in the same document but in different Paragraph (or paragraph-like block) elements - e.g. start in paragraph 1 and end in paragraph 2 of a FlowDocument.
Common situations: Selecting across multiple paragraphs and passing the selection endpoints to create a paragraph-scoped Span; using document-wide Start/End pointers; processing a document line-by-line but pairing pointers from adjacent paragraphs.
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.InDifferentTextContainers, "start", "end")
- SR.Format(SR.NotInAssociatedContainer, "position")
- " }} " 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/e800d9ed37983f40.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/Span.cs:109
{
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"));
}
// If start or end positions have a Hyperlink ancestor, we cannot split them.
Inline nonMergeableAncestor;
if ((nonMergeableAncestor = start.GetNonMergeableInlineAncestor()) != null)
{
throw new InvalidOperationException(SR.Format(SR.TextSchema_CannotSplitElement, nonMergeableAncestor.GetType().Name));
}
if ((nonMergeableAncestor = end.GetNonMergeableInlineAncestor()) != null)
{
throw new InvalidOperationException(SR.Format(SR.TextSchema_CannotSplitElement, nonMergeableAncestor.GetType().Name));
}
TextElement commonAncestor = TextElement.GetCommonAncestor((TextElement)start.Parent, (TextElement)end.Parent);
while (start.Parent != commonAncestor)
{
start = SplitElement(start);View on GitHub (pinned to 81131a70a4)