dotnet/wpf · error · ArgumentOutOfRangeException

SR.RangeValueMin

Error message

SR.RangeValueMin

What it means

WindowsScrollBar.SetScrollValue validates the lower bound: if val < si.nMin (the scrollbar's minimum from GetScrollInfo) it throws ArgumentOutOfRangeException with SR.RangeValueMin. RangeValue values below the control's minimum are rejected.

Solutions

  1. Clamp the value to at least RangeValue.Current.Minimum before calling SetValue.
  2. Refresh the pattern properties immediately before the call rather than using stale cached values.
  3. Catch ArgumentOutOfRangeException and retry with the clamped value.

Example fix

// before
rangeValue.SetValue(0);
// after
var rv = (RangeValuePattern)el.GetCurrentPattern(RangeValuePattern.Pattern);
rangeValue.SetValue(Math.Max(0, rv.Current.Minimum));
Defensive patterns

Strategy: validation

Validate before calling

var rv = (RangeValuePattern)element.GetCurrentPattern(RangeValuePattern.Pattern);
val = Math.Max(val, rv.Current.Minimum);

Try / catch

try { rv.SetValue(val); }
catch (ArgumentOutOfRangeException) { rv.SetValue(rv.Current.Minimum); }

Prevention

When it happens

Trigger: RangeValuePattern.SetValue with a value smaller than the scrollbar's nMin, at WindowsScrollBar.cs:683 — e.g. passing 0 or a negative value on a scrollbar whose min is not 0.

Common situations: Assuming scrollbar range starts at 0; using cached Minimum after the control changed range; off-by-one math when converting positions to percentages.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WindowsScrollBar.cs:683

            string classname = Misc.GetClassName(_hwnd);
            if (classname.ToLower(System.Globalization.CultureInfo.InvariantCulture).Contains("richedit"))
            {
                max = si.nMax - si.nPage;
            }
            else
            {
                max = (si.nMax - si.nPage) + (si.nPage > 0 ? 1 : 0);
            }

            // Explicit comparisions are made to the MaxPercentage and MinPercentage,
            // so that we dont miss out the fractions
            if (val > max )
            {
                throw new ArgumentOutOfRangeException("value", val, SR.RangeValueMax);
            }
            else if (val < si.nMin)
            {
                throw new ArgumentOutOfRangeException("value", val, SR.RangeValueMin);
            }

            if (_sbFlag == NativeMethods.SB_CTL)
            {
                Misc.SetScrollPos(_hwnd, _sbFlag, val, true);
            }
            else
            {
                // Determine the msg from the style.
                int msg =
                    IsScrollBarVertical(_hwnd, _sbFlag) ? NativeMethods.WM_VSCROLL : NativeMethods.WM_HSCROLL;

                // An application is generally programmed to process either the
                // SB_THUMBTRACK or SB_THUMBPOSITION request code.
                int wParam = NativeMethods.Util.MAKELONG ((short) NativeMethods.SB_THUMBPOSITION, (short) val);
                Misc.ProxySendMessage(_hwnd, msg, (IntPtr)wParam, IntPtr.Zero);
                wParam = NativeMethods.Util.MAKELONG ((short) NativeMethods.SB_THUMBTRACK, (short) val);
                Misc.ProxySendMessage(_hwnd, msg, (IntPtr)wParam, IntPtr.Zero);

View on GitHub (pinned to 81131a70a4)