JamesNK/Newtonsoft.Json · error · ArgumentException
Target type {0} is not a value type or a non-abstract class.
Error message
Target type {0} is not a value type or a non-abstract class. What it means
ConvertUtils.Convert throws this (as ArgumentException) when TryConvertInternal returns ConvertResult.NotInstantiableType (ConvertUtils.cs:390-391). That happens when the target type is an interface, an open generic type definition, or an abstract class (ConvertUtils.cs:581-585) — none of which can be instantiated or meaningfully converted into.
Source
Thrown at Src/Newtonsoft.Json/Utilities/ConvertUtils.cs:391
{
Success = 0,
CannotConvertNull = 1,
NotInstantiableType = 2,
NoValidConversion = 3
}
[RequiresUnreferencedCode(MiscellaneousUtils.TrimWarning)]
[RequiresDynamicCode(MiscellaneousUtils.AotWarning)]
public static object Convert(object initialValue, CultureInfo culture, Type targetType)
{
switch (TryConvertInternal(initialValue, culture, targetType, out object? value))
{
case ConvertResult.Success:
return value!;
case ConvertResult.CannotConvertNull:
throw new Exception("Can not convert null {0} into non-nullable {1}.".FormatWith(CultureInfo.InvariantCulture, initialValue.GetType(), targetType));
case ConvertResult.NotInstantiableType:
throw new ArgumentException("Target type {0} is not a value type or a non-abstract class.".FormatWith(CultureInfo.InvariantCulture, targetType), nameof(targetType));
case ConvertResult.NoValidConversion:
throw new InvalidOperationException("Can not convert from {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, initialValue.GetType(), targetType));
default:
throw new InvalidOperationException("Unexpected conversion result.");
}
}
[RequiresUnreferencedCode(MiscellaneousUtils.TrimWarning)]
[RequiresDynamicCode(MiscellaneousUtils.AotWarning)]
private static bool TryConvert(object? initialValue, CultureInfo culture, Type targetType, out object? value)
{
try
{
if (TryConvertInternal(initialValue, culture, targetType, out value) == ConvertResult.Success)
{
return true;
}
View on GitHub (pinned to 4f73e74372)
Solutions
- Pass a concrete, closed type (List<object>, a concrete subclass) as the target.
- Resolve the concrete runtime type before conversion (e.g. via a factory or type mapping).
- If the source is JSON, configure JsonSerializerSettings/ContractResolver to pick a concrete type for the property.
- Validate targetType with !targetType.IsAbstract && !targetType.IsInterface && !targetType.IsGenericTypeDefinition before calling Convert.
Example fix
// before object o = ConvertUtils.Convert(value, culture, typeof(IEnumerable)); // after object o = ConvertUtils.Convert(value, culture, typeof(List<object>));
Defensive patterns
Strategy: validation
Validate before calling
// Reject interfaces/open-generics/abstract types before calling Convert.
static void EnsureInstantiable(Type t) {
if (t.IsInterface || t.IsAbstract || t.IsGenericTypeDefinition)
throw new ArgumentException($"Target type {t} must be a concrete, closed type.");
} Type guard
static bool IsInstantiable(Type t) => !t.IsInterface && !t.IsAbstract && !t.IsGenericTypeDefinition;
Try / catch
try { return ConvertUtils.Convert(value, culture, targetType); } catch (ArgumentException ex) when (ex.Message.Contains("not a value type or a non-abstract class")) { /* resolve a concrete subtype */ } Prevention
- Always pass a concrete, closed type as the conversion target.
- Validate targetType with IsInstantiable before converting.
- Resolve abstract/interface properties to a concrete type via a contract resolver.
When it happens
Trigger: Calling ConvertUtils.Convert (directly or via the deserialization pipeline) with targetType equal to an interface (IEnumerable, IList), an open generic (typeof(List<>)), or an abstract base class.
Common situations: Reflection/generic code that loses the concrete type and passes an interface or open generic as the target; misconfigured contracts that resolve a property to an abstract type; dynamic typing losing closure.
Related errors
- Cannot convert {0} to BigInteger.
- Can not convert from {0} to {1}.
- Could not cast or convert from {0} to {1}.
- Argument is not a JToken.
- New item to be added to collection must be compatible with {
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/d88bf8bada4b3d2f.
Report an issue: GitHub.