JamesNK/Newtonsoft.Json · error · ArgumentException

Can not convert {0} to byte array.

Error message

Can not convert {0} to byte array.

What it means

Thrown at the FIRST guard in 'operator byte[]?(JToken?)' when ValidateToken fails. Allowed types are BytesTypes ({Bytes, String, Comment, Raw, Integer}) and the overload is nullable (JSON null returns null). ArgumentException {0} is the resolved JTokenType. So this throw means the token resolved to a JValue whose Type is Float, Boolean, Date, Guid, Uri, TimeSpan, Object, Array, or the token is not a JValue (EnsureValue null). A second, separate throw (error 133) covers the post-validation fallthrough.

Source

Thrown at Src/Newtonsoft.Json/Linq/JToken.cs:1395

            return Convert.ToUInt64(v.Value, CultureInfo.InvariantCulture);
        }

        /// <summary>
        /// Performs an explicit conversion from <see cref="JToken"/> to <see cref="Byte"/>[].
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns>The result of the conversion.</returns>
        public static explicit operator byte[]?(JToken? value)
        {
            if (value == null)
            {
                return null;
            }

            JValue? v = EnsureValue(value);
            if (v == null || !ValidateToken(v, BytesTypes, false))
            {
                throw new ArgumentException("Can not convert {0} to byte array.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
            }

            if (v.Value is string)
            {
                return Convert.FromBase64String(Convert.ToString(v.Value, CultureInfo.InvariantCulture)!);
            }
#if HAVE_BIG_INTEGER
            if (v.Value is BigInteger integer)
            {
                return integer.ToByteArray();
            }
#endif

            if (v.Value is byte[] bytes)
            {
                return bytes;
            }

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Ensure the producer emits binary data as a base64 string and index the scalar node.
  2. Guard token["hash"]?.Type is in {Bytes, String, Comment, Raw} before the cast (treat Integer as risky — see error 133).
  3. Use token["hash"]?.Value<byte[]>() which returns null on incompatible shapes.
  4. If the field is genuinely numeric, parse it to bytes yourself rather than relying on the cast.

Example fix

// before
byte[] hash = (byte[])payload["hash"]; // throws when hash is a number/object

// after
byte[] hash = (payload["hash"]?.Type == JTokenType.String) ? (byte[])payload["hash"]!! : null;
Defensive patterns

Strategy: validation

Validate before calling

byte[]? hash = (payload["hash"]?.Type == JTokenType.String || payload["hash"]?.Type == JTokenType.Bytes)
    ? (byte[])payload["hash"]!! : null;

Type guard

static bool IsBinaryCompatible(JToken? t) =>
    t is JValue v && (v.Type == JTokenType.Bytes || v.Type == JTokenType.String);

Try / catch

byte[]? hash;
try { hash = (byte[])payload["hash"]; }
catch (ArgumentException) { hash = null; }

Prevention

When it happens

Trigger: Calling (byte[])token["hash"] where the resolved JTokenType is Float, Boolean, Date, Guid, Uri, TimeSpan, Object, or Array, or the node is a JObject/JArray/JConstructor. A base64 string, a raw byte[] JValue, a Comment, or an Integer pass this guard (Integer then risks error 133).

Common situations: Binary/hash field emitted as a number (Float) or object instead of a base64 string; field changed to a boolean flag; mis-indexing into a child object/array.

Related errors


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