JamesNK/Newtonsoft.Json · error · ArgumentException

Can not convert {0} to SByte.

Error message

Can not convert {0} to SByte.

What it means

Thrown by the explicit (non-nullable) cast operator sbyte(JToken) at JToken.cs:933. The token type must be in NumberTypes = {Integer, Float, String, Comment, Raw, Boolean}. A JSON null, a Date/Guid/Uri/Bytes value, or a container (JObject/JArray) fails this ArgumentException. Out-of-range values fail later with OverflowException.

Source

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

                return (byte)integer;
            }
#endif

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

        /// <summary>
        /// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.SByte"/>.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns>The result of the conversion.</returns>
        [CLSCompliant(false)]
        public static explicit operator sbyte(JToken value)
        {
            JValue? v = EnsureValue(value);
            if (v == null || !ValidateToken(v, NumberTypes, false))
            {
                throw new ArgumentException("Can not convert {0} to SByte.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
            }

#if HAVE_BIG_INTEGER
            if (v.Value is BigInteger integer)
            {
                return (sbyte)integer;
            }
#endif

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

        /// <summary>
        /// Performs an explicit conversion from <see cref="JToken"/> to <see cref="Nullable{T}"/> of <see cref="Int32"/> .
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns>The result of the conversion.</returns>
        public static explicit operator int?(JToken? value)

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Use the nullable cast (sbyte?)token and coalesce: ((sbyte?)token) ?? (sbyte)0.
  2. Guard with token.Type == JTokenType.Integer before the cast.
  3. Use token.Value<sbyte?>() to tolerate null/missing.
  4. Deserialize into a nullable sbyte POCO property.

Example fix

// before
sbyte code = (sbyte)token["code"]; // throws when code is null

// after
sbyte code = (sbyte?)token["code"] ?? (sbyte)0;
Defensive patterns

Strategy: type-guard

Validate before calling

// Verify the token is a number-compatible scalar before the non-nullable sbyte cast
static bool CanToSByte(JToken? t) =>
    t is JValue v && (v.Type == JTokenType.Integer || v.Type == JTokenType.Float
                      || v.Type == JTokenType.String || v.Type == JTokenType.Boolean);

Type guard

static sbyte? SafeSByte(JToken? t) => t switch {
    JValue v when v.Type is JTokenType.Integer or JTokenType.Float
                       or JTokenType.String or JTokenType.Boolean => (sbyte?)t,
    JValue v when v.Type is JTokenType.Null or JTokenType.Undefined => null,
    _ => null
};

Try / catch

try
{
    sbyte s = (sbyte)token;
}
catch (ArgumentException ex) when (ex.Message.StartsWith("Can not convert"))
{
    // token is null/container/date; default to 0
}

Prevention

When it happens

Trigger: Casting a JSON null JValue to (sbyte)token; casting a Date/Object/Array/Guid to sbyte; an omitted sbyte field parsed as null.

Common situations: A signed-byte field that came back null or as an object; reading a Date value as an sbyte.

Related errors


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