dotnet/wpf · error · InvalidOperationException
SR.TextSegmentsMustNotOverlap
Error message
SR.TextSegmentsMustNotOverlap
What it means
TextAnchor keeps its segments in a sorted, non-overlapping list. InsertSegment throws this InvalidOperationException when the new segment's Start falls before the End of the preceding segment — i.e. the segment would overlap an already-registered segment. Overlapping segments would break the anchor's ordering invariant, so the library rejects the insert.
Solutions
- Compute the segment so it does not intersect existing anchor segments; clamp its Start/End outside existing ranges.
- Clip the new range against existing segments (subtract overlaps) before calling AddTextSegment.
- Track existing segments (via the anchor's segment list) and merge/union ranges instead of inserting raw overlapping ones.
Example fix
// before
anchor.AddTextSegment(start, end); // may overlap existing segment
// after
if (!existingSegments.Any(s => start.CompareTo(s.End) < 0 && end.CompareTo(s.Start) > 0))
{
anchor.AddTextSegment(start, end);
} Defensive patterns
Strategy: validation
Validate before calling
bool overlaps = existingSegments.Any(s => newStart.CompareTo(s.End) < 0 && newEnd.CompareTo(s.Start) > 0); if (overlaps) /* merge/clip before AddTextSegment */;
Try / catch
try { anchor.AddTextSegment(start, end); }
catch (InvalidOperationException) { /* clip range and retry */ } Prevention
- Maintain your own sorted list of created segments and check intersection before inserting.
- Prefer union/merge operations over raw inserts for intersecting ranges.
- Compute annotation ranges from the same resolved offsets used for existing segments.
When it happens
Trigger: AddTextSegment or ExclusiveUnion inserting a segment whose Start is before the End of the segment at _segments[i-1].
Common situations: Annotation code creating two overlapping highlights over the same document text (e.g. highlight a range that intersects an existing highlight), or programmatic range computation that produces intersecting spans.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- anchorLocator.Parts
- annotation component
- InvalidEnumArgumentException("action", (int)action…
- InvalidEnumArgumentException("action", (int)action…
- InvalidOperationException
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/b4d2cdab78855f91.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Annotations/TextAnchor.cs:635
}
/// <summary>
/// Inserts a segment into this anchor in the right order. If the new segment
/// overlaps with existing anchors it throws an exception.
/// </summary>
private void InsertSegment(TextSegment newSegment)
{
int i = 0;
for (; i < _segments.Count; i++)
{
if (newSegment.Start.CompareTo(_segments[i].Start) < 0)
break;
}
// Make sure it starts after the one its being put behind
if (i > 0 && newSegment.Start.CompareTo(_segments[i - 1].End) < 0)
throw new InvalidOperationException(SR.TextSegmentsMustNotOverlap);
// Make sure it ends before the one its being put ahead of
if (i < _segments.Count && newSegment.End.CompareTo(_segments[i].Start) > 0)
throw new InvalidOperationException(SR.TextSegmentsMustNotOverlap);
_segments.Insert(i, newSegment);
}
/// <summary>
/// Creates a new segment with the specified pointers, but first
/// normalizes them to make sure they are on insertion positions.
/// </summary>
/// <param name="start">start of the new segment</param>
/// <param name="end">end of the new segment</param>
private static TextSegment CreateNormalizedSegment(ITextPointer start, ITextPointer end)
{
// Normalize the segment
if (start.CompareTo(end) == 0)View on GitHub (pinned to 81131a70a4)