dotnet/wpf · error · ArgumentException

SR.Format(SR.NegativeValue, "startIndex")

Error message

SR.Format(SR.NegativeValue, "startIndex")

What it means

DocumentSequenceTextPointer.GetTextInRun validates its arguments before delegating to the underlying child pointer. A negative startIndex is meaningless for a buffer offset, so it throws ArgumentException with the NegativeValue resource. This is strict input validation on a public ITextPointer API.

Solutions

  1. Clamp or assert startIndex >= 0 before the call.
  2. Fix the upstream offset computation that produced the negative value.
  3. Throw a descriptive error in the caller when the computed index is negative.

Example fix

// before
pointer.GetTextInRun(dir, buffer, index, count);
// after
if (index < 0) index = 0;
pointer.GetTextInRun(dir, buffer, index, count);
Defensive patterns

Strategy: validation

Validate before calling

if (startIndex < 0) throw new ArgumentOutOfRangeException(nameof(startIndex), startIndex, "Must be non-negative.");

Try / catch

try { pointer.GetTextInRun(dir, buffer, start, count); } catch (ArgumentException) { /* log invalid offset; clamp to 0 */ }

Prevention

When it happens

Trigger: Calling GetTextInRun(direction, textBuffer, startIndex, count) with startIndex < 0, e.g. a variable initialized to -1 as a sentinel or an underflowing computed offset.

Common situations: Arithmetic that can go negative when walking backwards through a buffer without clamping; passing an index derived from an empty or failed extraction; sentinel -1 values leaking into the call.

Related errors


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

Appendix: source

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

        public static int GetTextRunLength(DocumentSequenceTextPointer thisTp, LogicalDirection direction)
        {
            ValidationHelper.VerifyDirection(direction, "direction");

            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>

View on GitHub (pinned to 81131a70a4)