dotnet/wpf · error · ArgumentException
SR.AtLeastOnePropertyMustBeSpecified
Error message
SR.AtLeastOnePropertyMustBeSpecified
What it means
Automation.AddAutomationPropertyChangedEventHandler requires a non-empty properties array since there is nothing to listen to otherwise. Passing an empty AutomationProperty[] throws ArgumentException with SR.AtLeastOnePropertyMustBeSpecified. Null arguments are separately rejected by ArgumentNullException.ThrowIfNull.
Solutions
- Ensure at least one AutomationProperty is in the array before calling (e.g. AutomationElement.NameProperty, IsEnabledProperty)
- Add a guard in your code that skips registration (or logs) when the property list is empty
- Validate that the dynamic property-selection logic actually yields properties
Example fix
// before
var props = selected.Select(p => p.Property).ToArray();
Automation.AddAutomationPropertyChangedEventHandler(el, handler, TreeScope.Element, props);
// after
var props = selected.Select(p => p.Property).ToArray();
if (props.Length > 0)
{
Automation.AddAutomationPropertyChangedEventHandler(el, handler, TreeScope.Element, props);
} Defensive patterns
Strategy: validation
Validate before calling
if (properties == null || properties.Length == 0)
throw new InvalidOperationException("At least one AutomationProperty is required"); Try / catch
try { Automation.AddAutomationPropertyChangedEventHandler(el, handler, scope, props); }
catch (ArgumentException) { log.Warn("No properties selected; skipping registration"); } Prevention
- Guard dynamic property lists for emptiness before subscribing
- Never pass placeholder empty arrays in test scaffolding
When it happens
Trigger: Calling Automation.AddAutomationPropertyChangedEventHandler(element, handler, scope, new AutomationProperty[0]) or an array initialized without any properties.
Common situations: Building the properties array dynamically (filtering a list) and passing the empty result; copying sample code with a placeholder empty array; configuration selecting zero properties.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- SR.InvalidParameter
- SR.PropertyNotSupported
- " }} " element found. Expected fixed page element ( }} ).
- ' ' ContentType is not valid.
- ' ' ID is not a valid XSD ID.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/d25e4dd9c51eeb73.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/Automation.cs:222
/// Called by a client to add a listener for property changed events.
/// </summary>
/// <param name="element">Element on which to listen for property changed events.</param>
/// <param name="scope">Specifies whether to listen to property changes events on the specified element, and/or its ancestors and children.</param>
/// <param name="eventHandler">Callback object to call when a specified property change occurs.</param>
/// <param name="properties">Params array of properties to listen for changes in.</param>
public static void AddAutomationPropertyChangedEventHandler(
AutomationElement element, // reference element for listening to the event
TreeScope scope, // scope to listen to
AutomationPropertyChangedEventHandler eventHandler, // callback object
params AutomationProperty [] properties // listen for changes to these properties
)
{
ArgumentNullException.ThrowIfNull(element);
ArgumentNullException.ThrowIfNull(eventHandler);
ArgumentNullException.ThrowIfNull(properties);
if (properties.Length == 0)
{
throw new ArgumentException( SR.AtLeastOnePropertyMustBeSpecified );
}
// Check that no properties are interpreted properties
// If more interpreted properties are identified add a mapping of
// on interpreted properties to the real property that raises events.
foreach (AutomationProperty property in properties)
{
ArgumentNullException.ThrowIfNull(property, nameof(properties));
}
// Add a client-side listener for for this event request
EventListener l = new EventListener(AutomationElement.AutomationPropertyChangedEvent, scope, properties, CacheRequest.CurrentUiaCacheRequest);
ClientEventManager.AddListener(element, eventHandler, l);
}
/// <summary>
/// Called by a client to remove a listener for property changed events.
/// </summary>View on GitHub (pinned to 81131a70a4)