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

  1. Compute the segment so it does not intersect existing anchor segments; clamp its Start/End outside existing ranges.
  2. Clip the new range against existing segments (subtract overlaps) before calling AddTextSegment.
  3. 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

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


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)