dotnet/aspnetcore · error · InvalidOperationException
The type ' ' does not have an associated TypeConverter that…
Error message
The type '{0}' does not have an associated TypeConverter that supports conversion from a string. Apply 'TypeConverterAttribute' to the type to register a converter. What it means
Thrown by BindConverter.MakeTypeConverterConverter when parsing user input back into type T (string -> T) and T has no TypeConverter supporting ConvertFrom(typeof(string)). This is the inbound counterpart of 236: Blazor needs a converter to turn the posted string into the bound property's type.
Solutions
- Add a TypeConverterAttribute with a converter that implements CanConvertFrom(string) and ConvertFrom.
- Or bind a primitive property and map to the custom type on submit.
- Ensure the converter handles the empty string (return default(T) or report an error) to avoid edge-case failures.
Example fix
// before: no parse path for the custom type
public struct Money { public decimal Amount; }
<InputNumber @bind-Value="model.Price" />
// after: TypeConverter implementing ConvertFrom
[TypeConverter(typeof(MoneyConverter))]
public struct Money { public decimal Amount; public Money(decimal a){Amount=a;} }
public class MoneyConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext? c, Type? s) => s == typeof(string);
public override object? ConvertFrom(ITypeDescriptorContext? c, CultureInfo? ci, object v)
=> decimal.TryParse((string)v, NumberStyles.Currency, ci, out var d) ? new Money(d) : new Money(0m);
public override bool CanConvertTo(ITypeDescriptorContext? c, Type? t) => t == typeof(string);
public override object? ConvertTo(ITypeDescriptorContext? c, CultureInfo? ci, object? v, Type t)
=> v is Money m ? m.Amount.ToString("C", ci) : null;
} Defensive patterns
Strategy: type-guard
Validate before calling
var converter = TypeDescriptor.GetConverter(typeof(T));
if (converter == null || !converter.CanConvertFrom(typeof(string))) { /* add TypeConverter or bind a primitive */ } Type guard
static bool CanParse<T>() { var c = TypeDescriptor.GetConverter(typeof(T)); return c != null && c.CanConvertFrom(typeof(string)); } Prevention
- Implement both ConvertTo and ConvertFrom in any custom TypeConverter.
- Test parsing of empty strings and culture-specific formats.
- Bind primitives where possible to avoid round-trip pitfalls.
When it happens
Trigger: Using @bind on a property of a custom type that lacks a TypeConverter for parsing from string, so when the user submits input Blazor cannot produce a T from the entered text.
Common situations: Custom value types/POCOs bound to form inputs without a registered converter; binding a wrapper type that has a ToString but no parse path.
Related errors
- The type ' ' does not have an associated TypeConverter that…
- ' ' is flagged with SingleDelivery, but the selected…
- Authorization requires a cascading parameter of type Task
- Do not specify both 'Authorized' and 'ChildContent'.
- The authorization data specifies an authentication scheme…
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/cd21203cb945d1c5.
Report an issue: GitHub.
Appendix: source
Thrown at src/Components/Components/src/BindConverter.cs:2063
if (!elementParser(initialArray.GetValue(i), culture, out convertedArray[i]!))
{
value = default;
return false;
}
}
value = convertedArray;
return true;
}
}
[UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "We expect unknown underlying types are configured by application code to be retained.")]
private static BindParser<T> MakeTypeConverterConverter<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>()
{
var typeConverter = TypeDescriptor.GetConverter(typeof(T));
if (typeConverter == null || !typeConverter.CanConvertFrom(typeof(string)))
{
throw new InvalidOperationException(
$"The type '{typeof(T).FullName}' does not have an associated {typeof(TypeConverter).Name} that supports " +
$"conversion from a string. " +
$"Apply '{typeof(TypeConverterAttribute).Name}' to the type to register a converter.");
}
return ConvertWithTypeConverter;
bool ConvertWithTypeConverter(object? obj, CultureInfo? culture, out T value)
{
// We intentionally close-over the TypeConverter to cache it. The TypeDescriptor infrastructure is slow.
if (obj == null)
{
value = default!;
return true;
}
var converted = typeConverter.ConvertFrom(context: null, culture ?? CultureInfo.CurrentCulture, obj);
if (converted == null)
{View on GitHub (pinned to 3600ca084e)