JamesNK/Newtonsoft.Json · error · ArgumentException
Can not convert {0} to Decimal.
Error message
Can not convert {0} to Decimal. What it means
Thrown by the explicit nullable cast operator decimal?(JToken?) at JToken.cs:736. With nullable:true, JSON null/undefined tokens pass and return null. The ArgumentException is raised when the token is not a JValue (container) or its type is outside NumberTypes = {Integer, Float, String, Comment, Raw, Boolean} — e.g. Date, Guid, Uri, Bytes, Object, Array.
Source
Thrown at Src/Newtonsoft.Json/Linq/JToken.cs:736
}
#endif
/// <summary>
/// Performs an explicit conversion from <see cref="JToken"/> to <see cref="Nullable{T}"/> of <see cref="Decimal"/>.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator decimal?(JToken? value)
{
if (value == null)
{
return null;
}
JValue? v = EnsureValue(value);
if (v == null || !ValidateToken(v, NumberTypes, true))
{
throw new ArgumentException("Can not convert {0} to Decimal.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
}
#if HAVE_BIG_INTEGER
if (v.Value is BigInteger integer)
{
return (decimal?)integer;
}
#endif
return (v.Value != null) ? (decimal?)Convert.ToDecimal(v.Value, CultureInfo.InvariantCulture) : null;
}
/// <summary>
/// Performs an explicit conversion from <see cref="JToken"/> to <see cref="Nullable{T}"/> of <see cref="Double"/>.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>The result of the conversion.</returns>
public static explicit operator double?(JToken? value)View on GitHub (pinned to 4f73e74372)
Solutions
- Check token.Type is Integer, Float, or String before the cast.
- Use token.Value<decimal?>() to get default for incompatible tokens.
- Confirm the JSON carries a numeric (or numeric-string) scalar, not a nested object.
- Deserialize into a POCO with a nullable decimal property for schema enforcement.
Example fix
// before
decimal? amount = (decimal?)token["amount"]; // throws when amount is an object
// after
decimal? amount = (token["amount"]?.Type is JTokenType.Integer or JTokenType.Float or JTokenType.String)
? (decimal?)token["amount"]
: null; Defensive patterns
Strategy: type-guard
Validate before calling
// Verify the token is a number-compatible scalar (nullable cast tolerates JSON null)
static bool CanToNullableDecimal(JToken? t) =>
t is not JValue v || v.Type is JTokenType.Integer or JTokenType.Float
or JTokenType.String or JTokenType.Boolean or JTokenType.Null or JTokenType.Undefined; Type guard
static decimal? SafeDecimal(JToken? t) => t switch {
JValue v when v.Type is JTokenType.Integer or JTokenType.Float
or JTokenType.String or JTokenType.Boolean => (decimal?)t,
JValue v when v.Type is JTokenType.Null or JTokenType.Undefined => null,
_ => null // container or Date/Guid/etc.
}; Try / catch
try
{
decimal? d = (decimal?)token;
}
catch (ArgumentException ex) when (ex.Message.StartsWith("Can not convert"))
{
// token is a container or Date/Guid; default to null
} Prevention
- Check token.Type is Integer/Float/String before casting.
- Use token.Value<decimal?>() for tolerant default handling.
- Confirm the field is a numeric scalar, not a nested object.
- Deserialize into a nullable decimal POCO property.
When it happens
Trigger: Casting a Date/Guid/Uri/Bytes JValue or a JObject/JArray to (decimal?)token; a token whose Type is Date where a currency amount was expected. A JSON null returns null.
Common situations: A monetary field represented as a string-ified object or as a Date; a field re-typed to an object after an API change; reading a Guid identifier as a decimal amount.
Related errors
- Can not convert {0} to Boolean.
- Can not convert {0} to DateTimeOffset.
- Can not convert {0} to Int64.
- Can not convert {0} to DateTime.
- Can not convert {0} to Double.
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/0485452fce72caa9.
Report an issue: GitHub.