LykosAI/StabilityMatrix · error · ArgumentException
ConvertBack Target type
Error message
ConvertBack Target type {targetType.Name} must be assignable to {typeof(TSource).Name} What it means
NullableDefaultNumericConverter.ConvertBack validates that the binding target property's type (targetType) is assignable to the converter's generic source type TSource before unboxing the value. If Avalonia supplies a target type that is not compatible with TSource, the converter cannot safely unbox the value back to TSource, so it throws ArgumentException immediately. This is a programming/declaration error in the binding, not a runtime data issue.
Solutions
- Update the converter's generic type arguments in the XAML/Code declaration so TSource matches (or is a base of) the bound property's type.
- Change the bound view model property type to one assignable to TSource.
- Replace the converter with one whose TSource matches the actual target type used in the binding.
Example fix
<!-- before -->
<TextBlock Text="{Binding Count, Converter={StaticResource NullableDefaultNumericConverter}}" />
<!-- where converter is NullableDefaultNumericConverter<double, int> but Count is long -->
// after
public class CountConverter : NullableDefaultNumericConverter<long, int> { }
// now TSource (long) is assignable from the bound property type Defensive patterns
Strategy: type-guard
Validate before calling
bool IsConverterCompatible<TSource>(Type targetType) => typeof(TSource).IsAssignableFrom(targetType);
Type guard
static bool TargetMatches<TSource>(Type? targetType) => targetType is not null && typeof(TSource).IsAssignableFrom(targetType);
Try / catch
try
{
var value = converter.ConvertBack(visualValue, targetPropertyType, param, culture);
}
catch (ArgumentException ex)
{
logger.LogError(ex, "Converter generic type does not match binding target type");
return BindingOperations.DoNothing;
} Prevention
- Match the converter's generic TSource to the view model property type when adding bindings
- Recheck converter generic arguments after refactoring property types
- Keep one converter instance per source/target type pair to avoid misuse
When it happens
Trigger: Using NullableDefaultNumericConverter<TSource,TTarget> in a XAML/Code binding where the bound property's type is not assignable to TSource, e.g. binding ConvertBack against a non-nullable or unrelated numeric type, or swapping/reordering the generic arguments on the converter declaration.
Common situations: Refactoring a view model property type (int -> long or decimal) without updating the converter's generic arguments; copy-pasting a converter usage from a different property type; accidentally applying the converter to a non-numeric property.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Convert Target type must be assignable to
- Cannot convert NaN to a numeric type
- Specified argument was out of range of valid values…
- Specified argument was out of range of valid values.
- Font NotoSansJP not found
AI-assisted analysis of LykosAI/StabilityMatrix@af93d6ef57 (2026-09-12).
Data as JSON: /api/errors/b31e6537174df81e.
Report an issue: GitHub.
Appendix: source
Thrown at StabilityMatrix.Avalonia/Converters/NullableDefaultNumericConverter.cs:71
{
// ReSharper disable once LocalizableElement
throw new ArgumentException(
$"Convert Target type {targetType.Name} must be assignable to {typeof(TTarget).Name}"
);
}
return (TTarget?)System.Convert.ChangeType(value, typeof(TTarget));
}
/// <summary>
/// Convert a nullable value type to a value type
/// </summary>
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (!targetType.IsAssignableTo(typeof(TSource)))
{
// ReSharper disable once LocalizableElement
throw new ArgumentException(
$"ConvertBack Target type {targetType.Name} must be assignable to {typeof(TSource).Name}"
);
}
return Unbox((TTarget?)value);
}
public enum ReturnBehavior
{
DefaultValue,
Throw
}
}
View on GitHub (pinned to af93d6ef57)