dotnet/wpf · error · System.ArgumentException

SR.MustBeOfType: ' ' must be of type ' '. (args: value…

Error message

SR.MustBeOfType: '{0}' must be of type '{1}'. (args: value, TemplateBindingExpression)

What it means

TemplateBindingExpressionConverter.ConvertTo converts a TemplateBindingExpression to a MarkupExtension, and throws ArgumentException (SR.MustBeOfType) when the supplied value is not actually a TemplateBindingExpression. This is a defensive type check on the converter's input.

Solutions

  1. Pass a TemplateBindingExpression instance (e.g. obtained from reading a template's markup) to ConvertTo.
  2. Null-check / type-check the value before calling the converter.
  3. If converting other expression types, use their own dedicated converters (e.g. BindingExpression converters).

Example fix

// before
converter.ConvertTo(context, culture, someOtherExpression, typeof(MarkupExtension));
// after
if (someOtherExpression is TemplateBindingExpression tbe)
    converter.ConvertTo(context, culture, tbe, typeof(MarkupExtension));
Defensive patterns

Strategy: type-guard

Validate before calling

if (value is not TemplateBindingExpression) throw new InvalidOperationException("converter requires TemplateBindingExpression");

Type guard

static bool IsTemplateBindingExpression(object v) => v is TemplateBindingExpression;

Try / catch

try { result = converter.ConvertTo(ctx, culture, value, typeof(MarkupExtension)); }
catch (ArgumentException ex) { log(ex.Message); result = null; }

Prevention

When it happens

Trigger: Calling ConvertTo (directly or via TypeDescriptor/serialization) with destinationType == typeof(MarkupExtension) and a value that is not a TemplateBindingExpression — e.g. null or another expression type.

Common situations: XAML serialization/designer tooling or custom code invoking the converter with a wrongly-typed value; passing a BindingExpression where a TemplateBindingExpression is expected.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/TemplateBindingExpressionConverter.cs:45

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            if (destinationType == typeof(MarkupExtension))
            {
                return true;
            }
            return base.CanConvertTo(context, destinationType);
        }

        /// <summary>
        /// Converts to a MarkupExtension
        /// </summary>
        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(MarkupExtension))
            {
                TemplateBindingExpression templateBindingExpression = value as TemplateBindingExpression;
                if (templateBindingExpression == null)
                    throw new ArgumentException(SR.Format(SR.MustBeOfType, "value", "TemplateBindingExpression"));
                return templateBindingExpression.TemplateBindingExtension;
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }
    }


}


View on GitHub (pinned to 81131a70a4)