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

  1. Coerce both operands to the same type before comparing, e.g. compare token.Value<byte[]>() with another byte[] using a structural comparer.
  2. Validate the operand type with a guard: if (other is byte[] b) token.CompareTo(b).
  3. 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

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


AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07). Data as JSON: /api/errors/8460d2b341a542d1. Report an issue: GitHub.