JamesNK/Newtonsoft.Json · error · ArgumentException
Value is not a JToken.
Error message
Value is not a JToken.
What it means
Thrown by JsonFormatterConverter.Convert(object, Type) when the value handed to the IFormatterConverter is not a JToken. JsonFormatterConverter is the bridge used while deserializing ISerializable types (types implementing ISerializable with a serialization constructor); each value passed to the ISerializable constructor is expected to be a JToken parsed from the JSON stream.
Source
Thrown at Src/Newtonsoft.Json/Serialization/JsonFormatterConverter.cs:69
_contract = contract;
_member = member;
}
private T GetTokenValue<T>(object value)
{
ValidationUtils.ArgumentNotNull(value, nameof(value));
JValue v = (JValue)value;
return (T)System.Convert.ChangeType(v.Value, typeof(T), CultureInfo.InvariantCulture)!;
}
public object Convert(object value, Type type)
{
ValidationUtils.ArgumentNotNull(value, nameof(value));
if (!(value is JToken token))
{
throw new ArgumentException("Value is not a JToken.", nameof(value));
}
return _reader.CreateISerializableItem(token, type, _contract, _member)!;
}
public object Convert(object value, TypeCode typeCode)
{
ValidationUtils.ArgumentNotNull(value, nameof(value));
object? resolvedValue = (value is JValue v) ? v.Value : value;
return System.Convert.ChangeType(resolvedValue, typeCode, CultureInfo.InvariantCulture)!;
}
public bool ToBoolean(object value)
{
return GetTokenValue<bool>(value);
}View on GitHub (pinned to 4f73e74372)
Solutions
- Avoid implementing ISerializable for types you serialize as JSON; prefer plain POCOs with [JsonObject]/[JsonProperty].
- If ISerializable is required, ensure the serialization stream contains native JSON values that become JTokens.
- Remove or adjust any custom JsonConverter that reads ISerializable types and injects non-JToken values.
- Report a repro if reached through pure library code without custom converters.
Example fix
// before: ISerializable type with custom converter injecting non-JToken
[JsonConverter(typeof(MyBadConverter))]
[Serializable] public class Foo : ISerializable { ... }
// after: drop ISerializable, use POCO
public class Foo { public int Id { get; set; } public string Name { get; set; } } Defensive patterns
Strategy: validation
Validate before calling
if (!(value is Newtonsoft.Json.Linq.JToken)) throw new ArgumentException("expected a JToken"); Type guard
static bool IsJToken(object value) => value is Newtonsoft.Json.Linq.JToken;
Try / catch
try { JsonConvert.DeserializeObject<T>(json); }
catch (ArgumentException ex) when (ex.Message.Contains("Value is not a JToken")) {
logger.Error(ex, "ISerializable payload contained non-JToken value; review custom converters."); throw;
} Prevention
- Avoid implementing ISerializable on types you serialize as JSON.
- Don't write custom JsonConverters that re-enter ISerializable deserialization with raw objects.
- Keep ISerializable round-tripping inside Json.NET's native pipeline.
- Test ISerializable types with full serialize/deserialize round-trips.
When it happens
Trigger: Deserializing a type that implements ISerializable and whose SerializationInfo values are not JTokens. This is an internal-protocol error, typically caused by a custom JsonConverter or ISerializable implementation that hands non-JToken objects into the converter, or by an internal pipeline mismatch during ISerializable population.
Common situations: Mixing ISerializable types with custom converters, partial deserialization via JToken.ReadFrom creating non-token inputs, edge cases with $values / typewriting during ISerializable round-tripping, version mismatches where an ISerializable contract is reused incorrectly.
Related errors
- Unexpected BsonType value: {0}
- Unable to read beyond the end of the stream.
- Expected Bytes but got {0}.
- No object created.
- Expected JSON property '{0}'.
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/e9fc9d481010090b.
Report an issue: GitHub.