dotnet/wpf · error · ArgumentException

SR.Format(SR.PropertyConditionIncorrectType…

Error message

SR.Format(SR.PropertyConditionIncorrectType, property.ProgrammaticName, expectedType.Name)

What it means

FindItemByProperty (via PropertyValueValidateAndMap) checks that the condition value's runtime type is compatible with the property's expected type: null is only allowed for reference types, and otherwise value.GetType() must be assignable to the expected type. A mismatch throws ArgumentException with a message naming the property and expected type.

Solutions

  1. Convert the value to the property's expected type before calling (e.g. double.Parse for numeric properties)
  2. Never pass null for value-type properties; use AutomationElement.NotSupported to match all items
  3. Use pattern matching / Convert.ChangeType against the property info's Type

Example fix

// before
pattern.FindItemByProperty(null, RangeValuePatternIdentifiers.ValueProperty, "50"); // string vs double
// after
pattern.FindItemByProperty(null, RangeValuePatternIdentifiers.ValueProperty, 50.0);
Defensive patterns

Strategy: validation

Validate before calling

if (value != AutomationElement.NotSupported && value != null && !expectedType.IsInstanceOfType(value))
    throw new ArgumentException($"{property.ProgrammaticName} expects {expectedType.Name}");

Type guard

bool IsValidConditionValue(AutomationProperty p, object v) => v == AutomationElement.NotSupported || (v != null && p.GetType() != null && v is not null && v.GetType() != typeof(object) && !(v is string && p == AutomationElement.ControlTypeProperty));

Try / catch

try { pattern.FindItemByProperty(null, prop, value); } catch (ArgumentException) { value = ConvertValue(prop, value); }

Prevention

When it happens

Trigger: Passing a string where the property expects double (e.g. RangeValuePatternIdentifiers.ValueProperty); passing a value-type null (e.g. null for a bool property); passing the wrong enum/control-type object type to a property comparison.

Common situations: Stringly-typed configuration supplying property values from user input; binding UI values (always strings) into FindItemByProperty; refactoring that changed a property's expected type; culture/number parsing producing wrong types.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/ItemContainerPattern.cs:140

       #region Private Methods

        private object PropertyValueValidateAndMap(AutomationProperty property, object value)
        {
            AutomationPropertyInfo info;
            if (!Schema.GetPropertyInfo(property, out info))
            {
                throw new ArgumentException(SR.UnsupportedProperty);
            }

            // Check type is appropriate: NotSupported is allowed against any property,
            // null is allowed for any reference type (ie not for value types), otherwise
            // type must be assignable from expected type.
            Type expectedType = info.Type;
            if (value != AutomationElement.NotSupported &&
                ((value == null && expectedType.IsValueType)
                || (value != null && !expectedType.IsAssignableFrom(value.GetType()))))
            {
                throw new ArgumentException(SR.Format(SR.PropertyConditionIncorrectType, property.ProgrammaticName, expectedType.Name));
            }

            // Some types are handled differently in managed vs unmanaged - handle those here...
            if (value is AutomationElement)
            {
                // If this is a comparison against a Raw/LogicalElement,
                // save the runtime ID instead of the element so that we
                // can take it cross-proc if needed.
                value = ((AutomationElement)value).GetRuntimeId();
            }
            else if (value is ControlType)
            {
                // If this is a control type, use the ID, not the CLR object
                value = ((ControlType)value).Id;
            }
            else if (value is Rect rc)
            {
                value = new double[] { rc.Left, rc.Top, rc.Width, rc.Height };

View on GitHub (pinned to 81131a70a4)