dotnet/wpf · error · InvalidOperationException

Character offset not valid in TextRange.

Error message

Character offset not valid in TextRange.

What it means

The WindowsEditBoxRange constructor throws InvalidOperationException(InvalidTextRangeOffset) when start < 0 or end < start. It deliberately uses InvalidOperationException instead of ArgumentException because clients never construct ranges directly — the error surfaces from an upstream TextPattern operation such as cloning or selecting.

Solutions

  1. Validate/clamp offsets so 0 <= start <= end <= document length before constructing/cloning ranges.
  2. After Move(), check the range's endpoint values before further operations.
  3. Catch InvalidOperationException and reset to textPattern.DocumentRange.
  4. Avoid manual endpoint arithmetic; use MoveEndpointByRange/Move with sanitized counts.

Example fix

// before
range.Move(TextUnit.Character, -50); // may push start negative
var clone = range.Clone(); // InvalidOperationException
// after
int moved = range.Move(TextUnit.Character, -50);
if (moved < 50) range.MoveTo(0, 0); // clamp to document start before cloning
var clone = range.Clone();
Defensive patterns

Strategy: validation

Validate before calling

bool valid = start >= 0 && end >= start && end <= textPattern.DocumentRange.GetText(int.MaxValue).Length;

Try / catch

try { var clone = range.Clone(); }
catch (InvalidOperationException) { range = textPattern.DocumentRange; }

Prevention

When it happens

Trigger: TextPattern operations that compute a range with negative start or end-before-start: e.g. cloning a corrupted range, Move/MoveEndpointByUnit producing an out-of-document offset, or RangeFromChild-style flows handing bad coordinates.

Common situations: Automation code that repeatedly Move()s a range past the beginning of the document and then clones it; arithmetic on range endpoints that inverts start/end; interop with providers that returned wrong offsets.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/4726017eecfb334f. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WindowsEditBoxRange.cs:37

    // For example the EM_LINEINDEX message converts a line number to it's starting character position.
    // Perhaps not the best choice but we use it to be consistent.

    internal class WindowsEditBoxRange : ITextRangeProvider
    {
        //------------------------------------------------------
        //
        //  Constructor
        //
        //------------------------------------------------------
 
        internal WindowsEditBoxRange(WindowsEditBox provider, int start, int end)
        {
            if (start < 0 || end < start)
            {
                // i'm throwing an invalid operation exception rather than an argument exception because 
                // clients never call this constructor directly.  it always happens as a result of some 
                // other operation, e.g. cloning an existing TextPatternRange.
                throw new InvalidOperationException(SR.Format(SR.InvalidTextRangeOffset, GetType().FullName));
            }
            Debug.Assert(provider != null);

            _provider = provider;
            _start = start;
            _end = end;
        }

        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------
 
        #region Public Methods

        ITextRangeProvider ITextRangeProvider.Clone()
        {

View on GitHub (pinned to 81131a70a4)