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
- Pass a TemplateBindingExpression instance (e.g. obtained from reading a template's markup) to ConvertTo.
- Null-check / type-check the value before calling the converter.
- 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
- Type-check values before routing them to a specific TypeConverter
- Match expression types to their dedicated converters
- Never pass null to ConvertTo
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
- SR.Format(SR.MustBeOfType, nameof(value)…
- SR.MustBeOfType
- SR.AnnotationAdorner_NotUIElement
- SR.AudioVideo_InvalidDependencyObject
- SR.Format(SR.BadFixedTextPosition, "position")
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)