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
- Do not set progress bar values via UIA; drive the underlying application so it updates the progress itself
- If you need a settable range element, target a slider/trackbar control instead
- Read the current progress with RangeValuePattern.Value, which is supported
- 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
- Treat progress bars as read-only in UIA; only sliders/trackbars support SetValue
- Read progress via RangeValuePattern.Value, never write it
- Check e.Current.ClassName/ControlType (ProgressBar) before attempting SetValue
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
- Operation cannot be performed.
- Selection container does not support multiple selection.
- SR.CacheReqestCanOnlyPopTop
- SR.CacheReqestCantModifyWhileActive
- SR.CantPrefetchTextPattern
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)