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
- Pass -1 explicitly for unlimited text, or a non-negative value for truncation, before calling GetText.
- Clamp/normalize negative values: if (maxLength < 0 && maxLength != -1) maxLength = -1.
- 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
- Always pass -1 (not 0 or a negative sentinel) for unlimited text in UI Automation GetText.
- Clamp computed limits to >= 0 or -1 before calling range APIs.
- Document the -1 convention in any automation wrapper you build.
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
- ArgumentOutOfRangeException
- SR.TextRangeProvider_EmptyStringParameter
- ' ' is not a valid value for ' '.
- ArgumentException(message, name)
- ArgumentNullException(name)
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)