JamesNK/Newtonsoft.Json · error · ArgumentException

Can not convert {0} to UInt64.

Error message

Can not convert {0} to UInt64.

What it means

Thrown by the explicit cast operator 'operator ulong?(JToken?)' (Nullable<UInt64>) when the token is not resolvable to a numeric JValue. ArgumentException {0} is the resolved JTokenType; allowed types are NumberTypes ({Integer, Float, String, Comment, Raw, Boolean}). Nullable overload: null/JSON-null return null. Throw indicates a non-numeric shape (Date, Guid, Object, Array, etc.).

Source

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

        }

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

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

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

            return (v.Value != null) ? (ulong?)Convert.ToUInt64(v.Value, CultureInfo.InvariantCulture) : null;
        }

        /// <summary>
        /// Performs an explicit conversion from <see cref="JToken"/> to <see cref="Double"/>.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns>The result of the conversion.</returns>
        public static explicit operator double(JToken value)

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Check token["snowflakeId"]?.Type is Integer/Float/String/Boolean before the cast.
  2. Prefer token["snowflakeId"]?.Value<ulong>() to avoid the throw on shape mismatch.
  3. If ids may be negative, switch to long? instead of ulong?.
  4. If ids became GUIDs, change the consuming type to Guid? at the boundary.

Example fix

// before
ulong? id = (ulong?)payload["snowflakeId"]; // throws when id is a Guid

// after
ulong? id = payload["snowflakeId"]?.Value<ulong>();
Defensive patterns

Strategy: validation

Validate before calling

ulong? id = payload["snowflakeId"]?.Value<ulong>();

Type guard

static bool IsUnsignedNumeric(JToken? t) =>
    t is JValue v && (v.Type == JTokenType.Integer || v.Type == JTokenType.Float);

Try / catch

ulong? id;
try { id = (ulong?)payload["snowflakeId"]; }
catch (ArgumentException) { id = null; }

Prevention

When it happens

Trigger: Calling (ulong?)token["snowflakeId"] where the resolved JTokenType is Date, Guid, TimeSpan, Uri, Bytes, Object, or Array, or the node is a JObject/JArray (EnsureValue null). A negative number passes ValidateToken but throws OverflowException, not this error.

Common situations: Snowflake/64-bit id field migrated to a GUID/string; id node replaced by a nested object; unsigned id cast against a payload whose schema flipped to signed/negative ids.

Related errors


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