dotnet/wpf · error · ArgumentException

SR.UnsupportedAttribute

Error message

SR.UnsupportedAttribute

What it means

FindAttribute rejects the requested attribute because it is not registered in the UI Automation TextPattern attribute schema. Schema.GetAttributeInfo returned false, meaning the AutomationTextAttribute is unknown to the client-side TextPattern schema. The library throws ArgumentException because only attributes with an entry in the schema (including a known value type) can be queried.

Solutions

  1. Pass only attributes declared on TextPattern, e.g. TextPattern.BackgroundColorAttribute, TextPattern.FontNameAttribute, TextPattern.CultureAttribute.
  2. Verify the attribute comes from the TextPattern class and not another pattern or a custom attribute.
  3. If you need an attribute not in the schema, query it via the provider/UIA COM API directly instead of FindAttribute.

Example fix

// before
range.FindAttribute(someOtherPattern.Attribute, value, false);
// after
range.FindAttribute(TextPattern.FontNameAttribute, value, false);
Defensive patterns

Strategy: validation

Validate before calling

private static readonly HashSet<AutomationTextAttribute> Supported = new() {
    TextPattern.BackgroundColorAttribute, TextPattern.CultureAttribute,
    TextPattern.FontNameAttribute, TextPattern.FontSizeAttribute,
    TextPattern.FontWeightAttribute, TextPattern.ForegroundColorAttribute,
    TextPattern.HorizontalTextAlignmentAttribute, TextPattern.IsItalicAttribute,
    TextPattern.IsReadOnlyAttribute, TextPattern.IsSubscriptAttribute,
    TextPattern.IsSuperscriptAttribute, TextPattern.UnderlineStyleAttribute,
    TextPattern.AnnotationTypesAttribute, TextPattern.AnnotationObjectsAttribute,
    TextPattern.StyleNameAttribute, TextPattern.TextFlowDirectionsAttribute };
if (!Supported.Contains(attribute)) throw new NotSupportedException($"Attribute {attribute} not supported by TextPattern.");

Type guard

static bool IsTextPatternAttribute(AutomationTextAttribute a) =>
    a == TextPattern.BackgroundColorAttribute || a == TextPattern.CultureAttribute ||
    a == TextPattern.FontNameAttribute || a == TextPattern.FontSizeAttribute || /* ...full whitelist... */
    a == TextPattern.UnderlineStyleAttribute;

Try / catch

try { range.FindAttribute(attribute, value, false); }
catch (ArgumentException) { log.Warn($"Unsupported text attribute: {attribute.ProgrammaticName}"); }

Prevention

When it happens

Trigger: Calling TextPatternRange.FindAttribute with an AutomationTextAttribute that is not one of TextPattern's supported attributes (e.g. an attribute from a different pattern such as TablePattern or a custom provider attribute), or an attribute object fabricated/default-initialized rather than obtained from TextPattern's static fields.

Common situations: Developers generalize attribute-search code and pass attributes collected from other patterns; code written against a newer UIA spec attribute that the .NET WPF UIAutomationClient schema does not know; typos or reflection-produced attribute instances.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

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

        /// Searches for a subrange of text that has the specified attribute.
        /// To search the entire document use the text pattern's document range.
        /// </summary>
        /// <param name="attribute">The attribute to search for.</param>
        /// <param name="value">The value of the specified attribute to search for.  The value must be of the exact type specified for the 
        /// 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;
                }
            }

View on GitHub (pinned to 81131a70a4)