JamesNK/Newtonsoft.Json · error · JsonException
Index {0} not valid on {1}.
Error message
Index {0} not valid on {1}. What it means
Thrown by PathFilter.GetTokenIndex when a numeric index is applied to a token that is neither a JArray nor a JConstructor (e.g. a JObject or a scalar JValue), and ErrorWhenNoMatch is true. Indexing is only meaningful on ordered containers.
Source
Thrown at Src/Newtonsoft.Json/Linq/JsonPath/PathFilter.cs:45
else if (t is JConstructor c)
{
if (c.Count <= index)
{
if (settings?.ErrorWhenNoMatch ?? false)
{
throw new JsonException("Index {0} outside the bounds of JConstructor.".FormatWith(CultureInfo.InvariantCulture, index));
}
return null;
}
return c[index];
}
else
{
if (settings?.ErrorWhenNoMatch ?? false)
{
throw new JsonException("Index {0} not valid on {1}.".FormatWith(CultureInfo.InvariantCulture, index, t.GetType().Name));
}
return null;
}
}
protected static JToken? GetNextScanValue(JToken originalParent, JToken? container, JToken? value)
{
// step into container's values
if (container != null && container.HasValues)
{
value = container.First;
}
else
{
// finished container, move to parent
while (value != null && value != originalParent && value == value.Parent!.Last)
{View on GitHub (pinned to 4f73e74372)
Solutions
- Use a property filter ($.name) instead of an index when the token is an object.
- Check token.Type before applying the index path, or disable ErrorWhenNoMatch.
- Validate the root token type (array vs object) before running positional queries.
Example fix
// before
token.SelectTokens("$[0]", new JsonSelectSettings { ErrorWhenNoMatch = true }); // token is JObject
// after
token.SelectTokens("$.name", new JsonSelectSettings { ErrorWhenNoMatch = true }); Defensive patterns
Strategy: type-guard
Validate before calling
static bool SupportsIndex(JToken token)
{
return token is JArray || token is JConstructor;
} Type guard
bool IsIndexable(JToken t) => t is JArray || t is JConstructor;
Try / catch
try { token.SelectTokens("$[0]", settings).ToList(); }
catch (JsonException ex) when (ex.Message.Contains("not valid on"))
{ /* token is not an array/constructor; switch to property access */ } Prevention
- Verify the root token type before running positional index paths.
- Keep ErrorWhenNoMatch off for loosely-typed payloads.
When it happens
Trigger: Calling an index filter on a non-array token with strict matching. Example: token.SelectTokens("$[0]", new JsonSelectSettings { ErrorWhenNoMatch = true }) where token is a JObject. The path '$[0]' assumes array semantics on an object.
Common situations: Payload shape changed from array to object between API versions; the root token is an object but the path assumes an array; chained filters where an earlier filter unexpectedly returned a scalar; enabling strict matching on loosely-typed data.
Related errors
- Path ended with open query.
- Unknown escape character: \
- Path ended with an open string.
- Path ended with an open regex.
- Could not read query operator.
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/e239fa3e903cc6c1.
Report an issue: GitHub.