dotnet/wpf · error · ArgumentException

SR.TextRangeProvider_InvalidParameterValue

Error message

SR.TextRangeProvider_InvalidParameterValue

What it means

TextRangeAdaptor's ITextRangeProvider.GetText(int maxLength) throws ArgumentException (SR.TextRangeProvider_InvalidParameterValue) when maxLength is negative and not exactly -1. Per the UI Automation contract, only -1 means 'no limit'; any other negative value is an invalid parameter.

Solutions

  1. Pass -1 explicitly for unlimited text, or a non-negative value for truncation, before calling GetText.
  2. Clamp/normalize negative values: if (maxLength < 0 && maxLength != -1) maxLength = -1.
  3. Catch ArgumentException in wrapper layers and log the offending maxLength value to find the caller passing bad limits.

Example fix

// before
string text = range.GetText(requested - overhead); // may be negative

// after
int maxLength = requested - overhead;
if (maxLength < 0) maxLength = -1; // -1 means no limit
string text = range.GetText(maxLength);
Defensive patterns

Strategy: validation

Validate before calling

if (maxLength < 0 && maxLength != -1)
    throw new ArgumentOutOfRangeException(nameof(maxLength), maxLength, "Must be >= 0 or exactly -1");
string text = range.GetText(maxLength);

Type guard

static bool IsValidGetTextLimit(int n) => n >= 0 || n == -1;

Prevention

When it happens

Trigger: Calling ITextRangeProvider.GetText(maxLength) on a WPF text range with values like -2, -10, or any negative int other than -1.

Common situations: Automation clients computing a length limit via arithmetic that underflows (e.g. desiredLength - extra), passing unvalidated ints from config or P/Invoke marshalling, or mixing conventions where 0/negative means 'unlimited'.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/TextRangeAdaptor.cs:1854

            Normalize();

            AutomationPeer peer = GetEnclosingAutomationPeer(_start, _end);
            Invariant.Assert(peer != null);
            IRawElementProviderSimple provider = ProviderFromPeer(peer);
            Invariant.Assert(provider != null);
            return provider;
        }

        /// <summary>
        /// Retrieves the text of the range.
        /// </summary>
        /// <param name="maxLength">Specifies the maximum length of the string to return or -1 if no limit is requested.</param>
        /// <returns>The text of the range possibly truncated to the specified limit.</returns>
        string ITextRangeProvider.GetText(int maxLength)
        {
            if (maxLength < 0 && maxLength != -1)
            {
                throw new ArgumentException(SR.Format(SR.TextRangeProvider_InvalidParameterValue, maxLength, "maxLength"));
            }

            Normalize();

            string text = TextRangeBase.GetTextInternal(_start, _end);
            return (text.Length <= maxLength || maxLength == -1) ? text : text.Substring(0, maxLength);
        }

        /// <summary>
        /// Moves the range the specified number of units in the text.  Note that the text is not altered.  Instead the
        /// range spans a different part of the text.
        /// If the range is degenerate, this method tries to move the insertion point count units.  If the range is nondegenerate 
        /// and count is greater than zero, this method collapses the range at its end point, moves the resulting range forward 
        /// to a unit boundary (if it is not already at one), and then tries to move count - 1 units forward. If the range is 
        /// nondegenerate and count is less than zero, this method collapses the range at the starting point, moves the resulting 
        /// range backward to a unit boundary (if it isn't already at one), and then tries to move |count| - 1 units backward. 
        /// Thus, in both cases, collapsing a nondegenerate range, whether or not moving to the start or end of the unit following 
        /// the collapse, counts as a unit.

View on GitHub (pinned to 81131a70a4)