{"record":{"id":"b31e6537174df81e","repo":"LykosAI/StabilityMatrix","slug":"convertback-target-type-targettype-name-must-be-assignable","errorCode":null,"errorMessage":"ConvertBack Target type {targetType.Name} must be assignable to {typeof(TSource).Name}","messagePattern":"ConvertBack Target type (.+?) must be assignable to (.+?)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"StabilityMatrix.Avalonia/Converters/NullableDefaultNumericConverter.cs","lineNumber":71,"sourceCode":"        {\n            // ReSharper disable once LocalizableElement\n            throw new ArgumentException(\n                $\"Convert Target type {targetType.Name} must be assignable to {typeof(TTarget).Name}\"\n            );\n        }\n\n        return (TTarget?)System.Convert.ChangeType(value, typeof(TTarget));\n    }\n\n    /// <summary>\n    /// Convert a nullable value type to a value type\n    /// </summary>\n    public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)\n    {\n        if (!targetType.IsAssignableTo(typeof(TSource)))\n        {\n            // ReSharper disable once LocalizableElement\n            throw new ArgumentException(\n                $\"ConvertBack Target type {targetType.Name} must be assignable to {typeof(TSource).Name}\"\n            );\n        }\n\n        return Unbox((TTarget?)value);\n    }\n\n    public enum ReturnBehavior\n    {\n        DefaultValue,\n        Throw\n    }\n}\n","sourceCodeStart":53,"sourceCodeEnd":85,"githubUrl":"https://github.com/LykosAI/StabilityMatrix/blob/af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002/StabilityMatrix.Avalonia/Converters/NullableDefaultNumericConverter.cs#L53-L85","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"<!-- before -->\n<TextBlock Text=\"{Binding Count, Converter={StaticResource NullableDefaultNumericConverter}}\" />\n<!-- where converter is NullableDefaultNumericConverter<double, int> but Count is long -->\n\n// after\npublic class CountConverter : NullableDefaultNumericConverter<long, int> { }\n// now TSource (long) is assignable from the bound property type","handlingStrategy":"type-guard","validationCode":"bool IsConverterCompatible<TSource>(Type targetType) => typeof(TSource).IsAssignableFrom(targetType);","typeGuard":"static bool TargetMatches<TSource>(Type? targetType) => targetType is not null && typeof(TSource).IsAssignableFrom(targetType);","tryCatchPattern":"try\n{\n    var value = converter.ConvertBack(visualValue, targetPropertyType, param, culture);\n}\ncatch (ArgumentException ex)\n{\n    logger.LogError(ex, \"Converter generic type does not match binding target type\");\n    return BindingOperations.DoNothing;\n}","preventionTips":["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"],"tags":["avalonia","converter","binding","type-mismatch","argument-exception"],"backgroundTag":"incompatible-source-type","analyzedSha":"af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002","analyzedAt":"2026-09-12T19:02:43.389Z","contentChangedAt":"2026-09-12T19:02:43.389Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}