dotnet/wpf · error · ArgumentException

SR.Format(SR.StartIndexExceedsBufferSize, startIndex…

Error message

SR.Format(SR.StartIndexExceedsBufferSize, startIndex, textBuffer.Length)

What it means

GetTextInRun throws ArgumentException when startIndex exceeds textBuffer.Length, because the caller asked to begin copying text past the end of the destination buffer. The resource StartIndexExceedsBufferSize includes the supplied index and buffer length to help diagnose the mismatch.

Solutions

  1. Validate startIndex <= textBuffer.Length before the call and pass a correctly sized buffer.
  2. Recompute the index against the current buffer instead of caching it.
  3. Clamp startIndex to textBuffer.Length if appending semantics are intended.

Example fix

// before
pointer.GetTextInRun(dir, buffer, buffer.Length + 1, 0);
// after
var start = Math.Min(startIndex, buffer.Length);
pointer.GetTextInRun(dir, buffer, start, buffer.Length - start);
Defensive patterns

Strategy: validation

Validate before calling

if (startIndex > buffer.Length) throw new ArgumentOutOfRangeException(nameof(startIndex), startIndex, $"Exceeds buffer length {buffer.Length}.");

Try / catch

try { pointer.GetTextInRun(dir, buffer, start, count); } catch (ArgumentException) { start = Math.Min(start, buffer.Length); }

Prevention

When it happens

Trigger: Calling GetTextInRun(direction, textBuffer, startIndex, count) where startIndex > textBuffer.Length — typically a stale index after the buffer shrank or an index from a different buffer.

Common situations: Reusing an index computed for a previous (longer) buffer; off-by-one passing buffer.Length + 1; passing an index belonging to a sibling text container.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/DocumentSequenceTextPointer.cs:662

            return thisTp.ChildPointer.GetTextRunLength(direction);
        }

        /// <summary>
        /// <see cref="ITextPointer.GetTextInRun(LogicalDirection,char[],int,int)"/>
        /// </summary>
        /// <remarks>Only reutrn uninterrupted runs of text</remarks>
        public static int GetTextInRun(DocumentSequenceTextPointer thisTp, LogicalDirection direction, char[] textBuffer, int startIndex, int count)
        {
            ValidationHelper.VerifyDirection(direction, "direction");

            ArgumentNullException.ThrowIfNull(textBuffer);
            if (startIndex < 0)
            {
                throw new ArgumentException(SR.Format(SR.NegativeValue, "startIndex"));
            }
            if (startIndex > textBuffer.Length)
            {
                throw new ArgumentException(SR.Format(SR.StartIndexExceedsBufferSize, startIndex, textBuffer.Length));
            }
            if (count < 0)
            {
                throw new ArgumentException(SR.Format(SR.NegativeValue, "count"));
            }
            if (count > textBuffer.Length - startIndex)
            {
                throw new ArgumentException(SR.Format(SR.MaxLengthExceedsBufferSize, count, textBuffer.Length, startIndex));
            }

            return thisTp.ChildPointer.GetTextInRun(direction, textBuffer, startIndex, count);
        }

        /// <summary>
        /// <see cref="ITextPointer.GetAdjacentElement"/>
        /// </summary>
        /// <remarks>Return null if the embedded object does not exist</remarks>
        public static object GetAdjacentElement(DocumentSequenceTextPointer thisTp, LogicalDirection direction)

View on GitHub (pinned to 81131a70a4)