JamesNK/Newtonsoft.Json · error · JsonException
Index * not valid on {0}.
Error message
Index * not valid on {0}. What it means
Thrown during JSONPath evaluation when a wildcard array indexer (the [*] form, where ArrayIndexFilter.Index is null) is applied to a token that is not a JArray or JConstructor, and error reporting is enabled. The filter expected an array to enumerate all children but encountered another node type (JObject, JValue, JProperty, etc.), so it reports 'Index * not valid on {TypeName}'.
Source
Thrown at Src/Newtonsoft.Json/Linq/JsonPath/ArrayIndexFilter.cs:37
if (v != null)
{
yield return v;
}
}
else
{
if (t is JArray || t is JConstructor)
{
foreach (JToken v in t)
{
yield return v;
}
}
else
{
if (settings?.ErrorWhenNoMatch ?? false)
{
throw new JsonException("Index * not valid on {0}.".FormatWith(CultureInfo.InvariantCulture, t.GetType().Name));
}
}
}
}
}
}
}View on GitHub (pinned to 4f73e74372)
Solutions
- Inspect the actual token type at the path before applying the [*] wildcard and use a property access for objects.
- Call SelectTokens without errorWhenNoMatch (or ErrorWhenNoMatch=false) so a missing/non-array simply yields zero results.
- Normalize the source JSON so the field is always an array (wrap singletons in a list at deserialization time).
- Verify the path points at a JArray using token["data"] is JArray before selecting.
Example fix
// before
token.SelectTokens("$.data[*]", errorWhenNoMatch: true);
// after
var data = token["data"];
if (data is JArray arr)
{
foreach (var item in arr) { /* ... */ }
}
// else: data is a single object or null, handle accordingly Defensive patterns
Strategy: type-guard
Validate before calling
// Confirm the node is an array before applying [*]
var node = token.SelectToken("$.data");
if (node is JArray)
{
var items = token.SelectTokens("$.data[*]");
} Type guard
static bool IsJsonArray(JToken? t) => t is JArray;
Prevention
- Prefer SelectTokens without errorWhenNoMatch so non-array targets yield zero results silently.
- Type-check each path segment with 'is JArray' before wildcard indexing.
- Normalize single-object responses into one-element arrays at deserialization.
When it happens
Trigger: Calling token.SelectTokens("$.data[*]", errorWhenNoMatch: true) or SelectTokens with JsonSelectSettings { ErrorWhenNoMatch = true } where the node at 'data' resolves to a JObject or scalar JValue instead of a JArray. The wildcard branch (ArrayIndexFilter.cs:26-38) only iterates JArray/JConstructor; anything else plus ErrorWhenNoMatch throws.
Common situations: The upstream JSON schema changed so a field that used to be an array is now a single object or null; an API returns a single object instead of a list when there is one item; assuming an array where a polymorphic single-value shape is returned.
Related errors
- Array slice is not valid on {0}.
- Property '{0}' not valid on {1}.
- Properties {0} not valid on {1}.
- Array index expected.
- Unexpected character while parsing path indexer:
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/a9b28a1ef97766b6.
Report an issue: GitHub.