dotnet/wpf · error · ArgumentException

SR.NegativeValue

Error message

SR.NegativeValue

What it means

ITextPointer.GetTextInRun on FixedTextPointer throws ArgumentException(SR.NegativeValue) when the count parameter is negative. The count must be a non-negative number of characters to copy into the textBuffer starting at startIndex.

Solutions

  1. Clamp count to zero before calling: count = Math.Max(0, count).
  2. Fix the index computation so end >= start before subtracting.
  3. Validate arguments before the call and skip the call for empty ranges.
  4. Catch ArgumentException and log/repair the range computation.

Example fix

// before
int count = endIndex - startIndex; // may be negative
pointer.GetTextInRun(dir, buffer, 0, count);
// after
int count = Math.Max(0, endIndex - startIndex);
if (count > 0) pointer.GetTextInRun(dir, buffer, 0, count);
Defensive patterns

Strategy: validation

Validate before calling

int safeCount = Math.Max(0, requestedCount);
if (safeCount > 0) pointer.GetTextInRun(direction, buffer, startIndex, safeCount);

Try / catch

try { n = pointer.GetTextInRun(direction, buffer, startIndex, count); }
catch (ArgumentException) { n = 0; /* clamp and recompute */ }

Prevention

When it happens

Trigger: Calling GetTextInRun(direction, char[] textBuffer, startIndex, count) with count < 0 — typically an off-by-one or subtraction yielding -1.

Common situations: Computing count as (endIndex - startIndex) where indices are inverted or empty ranges produce negatives; passing an uninitialized variable; loop boundary errors.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/FixedTextPointer.cs:128

        }

        // <see cref="System.Windows.Documents.ITextPointer.GetTextInRun"/>
        string ITextPointer.GetTextInRun(LogicalDirection direction)
        {
            return TextPointerBase.GetTextInRun(this, direction);
        }

        /// <summary>
        /// <see cref="ITextPointer.GetTextInRun(LogicalDirection,char[],int,int)"/>
        /// </summary>
        /// <remarks>Only reutrn uninterrupted runs of text</remarks>
        int ITextPointer.GetTextInRun(LogicalDirection direction, char[] textBuffer, int startIndex, int count)
        {
            ValidationHelper.VerifyDirection(direction, "direction");
            ArgumentNullException.ThrowIfNull(textBuffer);
            if (count < 0)
            {
                throw new ArgumentException(SR.Format(SR.NegativeValue, "count"));
            }

            if (_flowPosition.GetPointerContext(direction) != TextPointerContext.Text)
            {
                return 0;
            }
            return _flowPosition.GetTextInRun(direction, count, textBuffer, startIndex);
        }

        /// <summary>
        /// <see cref="ITextPointer.GetAdjacentElement"/>
        /// </summary>
        /// <remarks>Return null if the embedded object does not exist</remarks>
        object ITextPointer.GetAdjacentElement(LogicalDirection direction)
        {
            ValidationHelper.VerifyDirection(direction, "direction");
            TextPointerContext tpc = _flowPosition.GetPointerContext(direction);
            if (!(tpc == TextPointerContext.EmbeddedElement || tpc == TextPointerContext.ElementStart || tpc == TextPointerContext.ElementEnd))

View on GitHub (pinned to 81131a70a4)