{"record":{"id":"4726017eecfb334f","repo":"dotnet/wpf","slug":"character-offset-not-valid-in-textrange","errorCode":null,"errorMessage":"Character offset not valid in TextRange.","messagePattern":"Character offset not valid in TextRange\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WindowsEditBoxRange.cs","lineNumber":37,"sourceCode":"    // For example the EM_LINEINDEX message converts a line number to it's starting character position.\n    // Perhaps not the best choice but we use it to be consistent.\n\n    internal class WindowsEditBoxRange : ITextRangeProvider\n    {\n        //------------------------------------------------------\n        //\n        //  Constructor\n        //\n        //------------------------------------------------------\n \n        internal WindowsEditBoxRange(WindowsEditBox provider, int start, int end)\n        {\n            if (start < 0 || end < start)\n            {\n                // i'm throwing an invalid operation exception rather than an argument exception because \n                // clients never call this constructor directly.  it always happens as a result of some \n                // other operation, e.g. cloning an existing TextPatternRange.\n                throw new InvalidOperationException(SR.Format(SR.InvalidTextRangeOffset, GetType().FullName));\n            }\n            Debug.Assert(provider != null);\n\n            _provider = provider;\n            _start = start;\n            _end = end;\n        }\n\n        //------------------------------------------------------\n        //\n        //  Public Methods\n        //\n        //------------------------------------------------------\n \n        #region Public Methods\n\n        ITextRangeProvider ITextRangeProvider.Clone()\n        {","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WindowsEditBoxRange.cs#L19-L55","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Validate/clamp offsets so 0 <= start <= end <= document length before constructing/cloning ranges.","After Move(), check the range's endpoint values before further operations.","Catch InvalidOperationException and reset to textPattern.DocumentRange.","Avoid manual endpoint arithmetic; use MoveEndpointByRange/Move with sanitized counts."],"exampleFix":"// before\nrange.Move(TextUnit.Character, -50); // may push start negative\nvar clone = range.Clone(); // InvalidOperationException\n// after\nint moved = range.Move(TextUnit.Character, -50);\nif (moved < 50) range.MoveTo(0, 0); // clamp to document start before cloning\nvar clone = range.Clone();","handlingStrategy":"validation","validationCode":"bool valid = start >= 0 && end >= start && end <= textPattern.DocumentRange.GetText(int.MaxValue).Length;","typeGuard":null,"tryCatchPattern":"try { var clone = range.Clone(); }\ncatch (InvalidOperationException) { range = textPattern.DocumentRange; }","preventionTips":["Check range endpoints after Move() before cloning.","Clamp offsets to [0, documentLength].","Don't hand-invert start/end when manipulating endpoints."],"tags":["uiautomation","textpattern","text-range","offset"],"backgroundTag":"value-out-of-range","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}