{"record":{"id":"a9b28a1ef97766b6","repo":"JamesNK/Newtonsoft.Json","slug":"index-not-valid-on-0","errorCode":null,"errorMessage":"Index * not valid on {0}.","messagePattern":"Index \\* not valid on (.+?)\\.","errorType":"exception","errorClass":"JsonException","httpStatus":null,"severity":"error","filePath":"Src/Newtonsoft.Json/Linq/JsonPath/ArrayIndexFilter.cs","lineNumber":37,"sourceCode":"                    if (v != null)\n                    {\n                        yield return v;\n                    }\n                }\n                else\n                {\n                    if (t is JArray || t is JConstructor)\n                    {\n                        foreach (JToken v in t)\n                        {\n                            yield return v;\n                        }\n                    }\n                    else\n                    {\n                        if (settings?.ErrorWhenNoMatch ?? false)\n                        {\n                            throw new JsonException(\"Index * not valid on {0}.\".FormatWith(CultureInfo.InvariantCulture, t.GetType().Name));\n                        }\n                    }\n                }\n            }\n        }\n    }\n}","sourceCodeStart":19,"sourceCodeEnd":44,"githubUrl":"https://github.com/JamesNK/Newtonsoft.Json/blob/4f73e74372445108d2c1bda37b36e6f5e43402e0/Src/Newtonsoft.Json/Linq/JsonPath/ArrayIndexFilter.cs#L19-L44","documentation":"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}'.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ntoken.SelectTokens(\"$.data[*]\", errorWhenNoMatch: true);\n\n// after\nvar data = token[\"data\"];\nif (data is JArray arr)\n{\n    foreach (var item in arr) { /* ... */ }\n}\n// else: data is a single object or null, handle accordingly","handlingStrategy":"type-guard","validationCode":"// Confirm the node is an array before applying [*]\nvar node = token.SelectToken(\"$.data\");\nif (node is JArray)\n{\n    var items = token.SelectTokens(\"$.data[*]\");\n}","typeGuard":"static bool IsJsonArray(JToken? t) => t is JArray;","tryCatchPattern":null,"preventionTips":["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."],"tags":["jsonpath","type-mismatch","array-indexer"],"analyzedSha":"4f73e74372445108d2c1bda37b36e6f5e43402e0","analyzedAt":"2026-08-07T06:10:08.596Z","schemaVersion":2},"datasetVersion":"2026-08-07T07:17:06.508Z"}