JamesNK/Newtonsoft.Json · error · ArgumentException

Source value must be a JToken.

Error message

Source value must be a JToken.

What it means

Thrown by the LINQ-to-JSON Value<T,U>(this IEnumerable<T>) extension when the source sequence is not itself a JToken. The extension accepts IEnumerable<T> (where T:JToken) for ergonomics (so a single JToken can be treated as a one-element sequence), but the conversion requires the actual instance to be a JToken; a collection type like List<JToken> or JArray satisfies the parameter type but fails this guard with ArgumentException.

Source

Thrown at Src/Newtonsoft.Json/Linq/Extensions.cs:178

        public static U? Value<U>(this IEnumerable<JToken> value)
        {
            return value.Value<JToken, U>();
        }

        /// <summary>
        /// Converts the value.
        /// </summary>
        /// <typeparam name="T">The source collection type.</typeparam>
        /// <typeparam name="U">The type to convert the value to.</typeparam>
        /// <param name="value">A <see cref="JToken"/> cast as a <see cref="IEnumerable{T}"/> of <see cref="JToken"/>.</param>
        /// <returns>A converted value.</returns>
        public static U? Value<T, U>(this IEnumerable<T> value) where T : JToken
        {
            ValidationUtils.ArgumentNotNull(value, nameof(value));

            if (!(value is JToken token))
            {
                throw new ArgumentException("Source value must be a JToken.");
            }

            return token.Convert<JToken, U>();
        }

        internal static IEnumerable<U?> Values<T, U>(this IEnumerable<T> source, object? key) where T : JToken
        {
            ValidationUtils.ArgumentNotNull(source, nameof(source));

            if (key == null)
            {
                foreach (T token in source)
                {
                    if (token is JValue value)
                    {
                        yield return Convert<JValue, U>(value);
                    }
                    else

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Call Value<T,U> only on a single JToken instance (e.g. a JValue/JProperty/JToken).
  2. For sequences use .Values<T>() / .Values<T,U>(key) which enumerates each token.
  3. Select a single token first: token.Children().First().Value<int>() rather than token.Children().Value<int>().

Example fix

// before
int v = tokens.Value<int>(); // tokens is List<JToken>

// after
IEnumerable<int> v = tokens.Values<int>();
Defensive patterns

Strategy: type-guard

Validate before calling

if (source is JToken token)
{
    var v = token.Value<int>();
}

Type guard

static bool IsSingleToken<T>(IEnumerable<T> source) where T : JToken
    => source is JToken;

Prevention

When it happens

Trigger: Calling .Value<object>() / .Value<int>() on a List<JToken>, an array of JToken, or any IEnumerable<JToken> that is not itself a JToken; passing a LINQ Where/Select result (which is a sequence, not a token) to Value<T,U>.

Common situations: Confusing the single-token Value<T,U> extension (on IEnumerable<T> narrowed to a JToken) with the Values<T> extension meant for collections; chaining .Children().Value<...>() where Children returns a sequence.

Related errors


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