JamesNK/Newtonsoft.Json · error · ArgumentException
Object must be of type byte[].
Error message
Object must be of type byte[].
What it means
Thrown by JValue.CompareTo (and therefore by all ordering/equality on JValue) when the token's JSON type is JTokenType.Bytes and the object being compared against is not a byte[]. Comparing two byte[] JValues compares the arrays element-wise via ByteArrayCompare; a mismatched operand type is rejected with this ArgumentException because there is no defined ordering between a byte[] and an arbitrary object.
Source
Thrown at Src/Newtonsoft.Json/Linq/JValue.cs:364
return dateA.CompareTo(dateB);
#if HAVE_DATE_TIME_OFFSET
}
else
{
DateTimeOffset offsetA = (DateTimeOffset)objA;
if (!(objB is DateTimeOffset offsetB))
{
offsetB = new DateTimeOffset(Convert.ToDateTime(objB, CultureInfo.InvariantCulture));
}
return offsetA.CompareTo(offsetB);
}
#endif
case JTokenType.Bytes:
if (!(objB is byte[] bytesB))
{
throw new ArgumentException("Object must be of type byte[].");
}
byte[]? bytesA = objA as byte[];
MiscellaneousUtils.Assert(bytesA != null);
return MiscellaneousUtils.ByteArrayCompare(bytesA!, bytesB);
case JTokenType.Guid:
if (!(objB is Guid))
{
throw new ArgumentException("Object must be of type Guid.");
}
Guid guid1 = (Guid)objA;
Guid guid2 = (Guid)objB;
return guid1.CompareTo(guid2);
case JTokenType.Uri:
Uri? uri2 = objB as Uri;View on GitHub (pinned to 4f73e74372)
Solutions
- Coerce both operands to the same type before comparing, e.g. compare token.Value<byte[]>() with another byte[] using a structural comparer.
- Validate the operand type with a guard: if (other is byte[] b) token.CompareTo(b).
- Avoid mixing JTokenType.Bytes values into collections that get sorted alongside non-byte[] tokens.
Example fix
// before
int c = byteToken.CompareTo("AQID");
// after
byte[] other = Convert.FromBase64String("AQID");
int c = byteToken.CompareTo(other); Defensive patterns
Strategy: type-guard
Validate before calling
if (other is byte[] b) { int c = byteToken.CompareTo(b); } Type guard
static bool IsByteArray(object? o) => o is byte[];
Try / catch
try { int c = token.CompareTo(other); } catch (ArgumentException ex) when (ex.Message.Contains("byte[]")) { /* coerce type */ } Prevention
- Always pass a byte[] when comparing byte-valued JValues.
- Coerce operands to the matching primitive before CompareTo.
- Avoid mixing JTokenType.Bytes with other types in sorted collections.
When it happens
Trigger: Comparing a JValue holding a byte[] (created from new JValue(new byte[]{1,2,3}) or parsed base64) against a non-byte[] operand, e.g. token.CompareTo("hello") or token.CompareTo(42). Also when sorting/mixing a JToken list containing byte[] values with values of other types.
Common situations: Binary/blob columns deserialized into JValue as byte[] then compared against string or int literals; sorting heterogeneous arrays; equality checks between a base64 token and a plain string.
Related errors
- Object must be of type Guid.
- Object must be of type Uri.
- Object must be of type TimeSpan.
- Could not determine JSON object type for type {0}.
- Cannot access child value on {0}.
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/8460d2b341a542d1.
Report an issue: GitHub.