JamesNK/Newtonsoft.Json · error · ArgumentException
Could not convert '{0}' to {1}.
Error message
Could not convert '{0}' to {1}. What it means
Thrown inside JToken.ToObject(Type) when the target type is an enum and the token's string value cannot be parsed to that enum. Newtonsoft first tries ToObject via JsonSerializer (to honour StringEnumConverter and [EnumMember] attributes); if that parse throws, the original exception is wrapped and re-thrown as ArgumentException with the offending string value ({0}) and the enum type name ({1}). This is a deliberate re-throw to surface a clearer, value-aware message.
Source
Thrown at Src/Newtonsoft.Json/Linq/JToken.cs:2035
public object? ToObject(Type objectType)
{
if (JsonConvert.DefaultSettings == null)
{
PrimitiveTypeCode typeCode = ConvertUtils.GetTypeCode(objectType, out bool isEnum);
if (isEnum)
{
if (Type == JTokenType.String)
{
try
{
// use serializer so JsonConverter(typeof(StringEnumConverter)) + EnumMemberAttributes are respected
return ToObject(objectType, JsonSerializer.CreateDefault());
}
catch (Exception ex)
{
Type enumType = objectType.IsEnum() ? objectType : Nullable.GetUnderlyingType(objectType)!;
throw new ArgumentException("Could not convert '{0}' to {1}.".FormatWith(CultureInfo.InvariantCulture, (string?)this, enumType.Name), ex);
}
}
if (Type == JTokenType.Integer)
{
Type enumType = objectType.IsEnum() ? objectType : Nullable.GetUnderlyingType(objectType)!;
return Enum.ToObject(enumType, ((JValue)this).Value!);
}
}
switch (typeCode)
{
case PrimitiveTypeCode.BooleanNullable:
return (bool?)this;
case PrimitiveTypeCode.Boolean:
return (bool)this;
case PrimitiveTypeCode.CharNullable:
return (char?)this;View on GitHub (pinned to 4f73e74372)
Solutions
- Inspect the actual string value in the JSON and reconcile it with the enum members (fix the typo or add the missing member).
- Configure StringEnumConverter with AllowIntegerValues / camelCase matching, or add [EnumMember(Value = "...")] for the producer's spelling.
- Parse defensively with Enum.TryParse before calling ToObject, falling back to a default enum value on mismatch.
Example fix
// before var status = token["status"].ToObject<Status>(); // after var raw = (string)token["status"]; var status = Enum.TryParse<Status>(raw, ignoreCase: true, out var s) ? s : Status.Unknown;
Defensive patterns
Strategy: validation
Validate before calling
var raw = (string)token;
if (!Enum.TryParse<MyEnum>(raw, ignoreCase: true, out _)) { /* handle before ToObject */ } Type guard
static bool IsValidEnumString<TEnum>(string s) where TEnum : struct => Enum.TryParse<TEnum>(s, ignoreCase: true, out _);
Try / catch
try { return token.ToObject<MyEnum>(); } catch (ArgumentException ex) when (ex.Message.StartsWith("Could not convert")) { /* default or log */ } Prevention
- Align producer enum strings with [EnumMember] attributes or a case-insensitive StringEnumConverter.
- Validate enum membership with Enum.TryParse before ToObject.
- Keep a regression test covering every enum member against sample payloads.
When it happens
Trigger: Calling token.ToObject(typeof(MyEnum)) or the generic ToObject<MyEnum>() on a JToken whose JSON value is a string that is not a valid member of the enum, e.g. "Pendng" for enum Status { Active, Pending, Closed }. The same path is hit when an integer-as-string or a member renamed via EnumMember is mis-spelled.
Common situations: Enum values are renamed in code but the JSON/producer is not updated. A producer sends a free-text status string that does not match any enum member. Locale/casing differences when StringEnumConverter is not configured to be case-insensitive. Migrating from int-backed enums to string-backed enums without regenerating sample data.
Related errors
- Unexpected merge array handling when merging JSON.
- Can not convert {0} to Boolean.
- Can not convert {0} to DateTimeOffset.
- Can not convert {0} to Int64.
- Can not convert {0} to DateTime.
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/76be8e043a51501d.
Report an issue: GitHub.