dotnet/wpf · error · System.InvalidOperationException

SR.ValueReadonly

Error message

SR.ValueReadonly

What it means

WindowsProgressbar proxies the Win32 progress bar control, whose value can only be set by the control's owner application, not by UI Automation clients. The IRangeValueProvider.SetValue implementation is intentionally read-only and throws InvalidOperationException(SR.ValueReadonly) to tell the caller that this property cannot be modified through UIA.

Solutions

  1. Do not set progress bar values via UIA; drive the underlying application so it updates the progress itself
  2. If you need a settable range element, target a slider/trackbar control instead
  3. Read the current progress with RangeValuePattern.Value, which is supported
  4. Update test logic to verify progress rather than set it

Example fix

// before
var range = progressBar.GetCurrentPattern(RangeValuePattern.Pattern) as RangeValuePattern;
range.SetValue(50); // throws InvalidOperationException
// after
var range = progressBar.GetCurrentPattern(RangeValuePattern.Pattern) as RangeValuePattern;
double progress = range.Value; // read-only: observe instead of set
Defensive patterns

Strategy: validation

Validate before calling

bool IsRangeValueSettable(AutomationElement e) { var p = e.GetCurrentPattern(RangeValuePattern.Pattern) as RangeValuePattern; return p != null && !e.Current.Name.Contains("progress") && e.Current.ClassName is string cn && cn.IndexOf("progress", StringComparison.OrdinalIgnoreCase) < 0; }

Type guard

bool IsSettableRange(AutomationElement e) => e.TryGetCurrentPattern(RangeValuePattern.Pattern, out var p) && !IsProgressBar(e);

Try / catch

try { rangePattern.SetValue(v); } catch (InvalidOperationException) { /* progress bar is read-only: observe with rangePattern.Value instead */ }

Prevention

When it happens

Trigger: Calling UIA RangeValuePattern.SetValue(value) on a progress bar element backed by the WindowsProgressbar proxy.

Common situations: Test or automation code that tries to 'set' progress bar progress to simulate state, confusing progress bars with sliders (which do support SetValue via RangeValue pattern).

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/WindowsProgressbar.cs:86

        //
        //------------------------------------------------------

        #region ProxySimple Interface
        
        // Returns a pattern interface if supported.
        internal override object GetPatternProvider (AutomationPattern iid)
        {
            return (iid == RangeValuePattern.Pattern) ? this : null;
        }

        #endregion
        
        #region RangeValue Pattern

        void IRangeValueProvider.SetValue (double val)
        {
            //This proxy is readonly
            throw new InvalidOperationException(SR.ValueReadonly);
        }

        // Request to get the value that this UI element is representing in a native format
        double IRangeValueProvider.Value
        {
            get
            {
                return (double)ValuePercent;
            }
        }

        bool IRangeValueProvider.IsReadOnly
        {
            get
            {
                return true;
            }
        }

View on GitHub (pinned to 81131a70a4)