dotnet/wpf · error · ArgumentException

SR.Format(SR.TextAttributeValueWrongType, attribute…

Error message

SR.Format(SR.TextAttributeValueWrongType, attribute, ai.Type.Name, value.GetType().Name)

What it means

FindAttribute validates that the search value's runtime type exactly matches the type registered for the attribute in the TextPattern schema (ai.Type). When the value type differs, the library throws ArgumentException naming the expected and actual types. This prevents sending a provider an attribute value it cannot interpret.

Solutions

  1. Cast or construct the value to the exact documented attribute type before calling FindAttribute.
  2. For ColorAttribute use System.Windows.Media.Color; for CultureAttribute use CultureInfo; for font-size/weight use the documented primitive type.
  3. Check the attribute's expected type via documentation or Schema, and validate with a type check before the call.

Example fix

// before
range.FindAttribute(TextPattern.FontSizeAttribute, 12, false); // int
// after
range.FindAttribute(TextPattern.FontSizeAttribute, 12.0, false); // double
Defensive patterns

Strategy: type-guard

Validate before calling

bool ok = value.GetType() == expectedTypeFor(attribute); // map each TextPattern attribute to its documented CLR type before calling FindAttribute

Type guard

static bool IsCorrectValueType(AutomationTextAttribute a, object v) =>
    (a == TextPattern.FontSizeAttribute && v is double) ||
    (a == TextPattern.BackgroundColorAttribute && v is System.Windows.Media.Color) ||
    (a == TextPattern.CultureAttribute && v is System.Globalization.CultureInfo) ||
    (a == TextPattern.FontWeightAttribute && v is int);
// use: if (IsCorrectValueType(attr, value)) range.FindAttribute(attr, value, false);

Try / catch

try { return range.FindAttribute(attribute, value, backwards); }
catch (ArgumentException ex) { throw new InvalidOperationException($"Value for {attribute.ProgrammaticName} must be of the documented type", ex); }

Prevention

When it happens

Trigger: Calling FindAttribute with a value whose GetType() is not exactly the attribute's declared type, e.g. passing an int boxed value for TextPattern.ForegroundColorAttribute (expects Color), a string for an attribute expecting double (IsHorizontalRulerAttribute-like boolean/double attributes), or a double where float is expected.

Common situations: Passing numeric literals (int) where the schema expects double or Color; using string values for enum-typed attributes instead of the enum itself; locale changes where CultureAttribute gets a string instead of CultureInfo.

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/5533e6c644482a0f. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClient/System/Windows/Automation/Text/TextRange.cs:185

        /// attribute.  For example when searching for font size you must specify the size in points as a double.
        /// If you specify the point size as an integer then you will never get any matches due to the differing types.</param>
        /// <param name="backward">true if the last occurring range should be returned instead of the first.</param>
        /// <returns>A subrange with the specified attribute, or null if no such subrange exists.</returns>
        public TextPatternRange FindAttribute(AutomationTextAttribute attribute, object value, bool backward)
        {
            ArgumentNullException.ThrowIfNull(attribute);
            ArgumentNullException.ThrowIfNull(value); // no text attributes can have null as a valid value

            // Check that attribute value is of expected type...
            AutomationAttributeInfo ai;
            if(!Schema.GetAttributeInfo(attribute, out ai))
            {
                throw new ArgumentException(SR.UnsupportedAttribute);
            }

            if (value.GetType() != ai.Type)
            {
                throw new ArgumentException(SR.Format(SR.TextAttributeValueWrongType, attribute, ai.Type.Name, value.GetType().Name), nameof(value));
            }

            // note: if we implement attributes whose values are logical elements, patterns,
            // or ranges then we'll need to unwrap the objects here before passing them on to
            // the provider.
            if (attribute == TextPattern.CultureAttribute)
            {
                if (value is CultureInfo)
                {
                    value = ((CultureInfo)value).LCID;
                }
            }

            SafeTextRangeHandle hResultTextRange = UiaCoreApi.TextRange_FindAttribute(_hTextRange, attribute.Id, value, backward);
            return Wrap(hResultTextRange, _pattern);
        }

        /// <summary>

View on GitHub (pinned to 81131a70a4)