{"record":{"id":"0ba4a71686eb509c","repo":"json-path/JsonPath","slug":"filter-s-can-only-be-applied-to-arrays-current","errorCode":null,"errorMessage":"Filter: %s can only be applied to arrays. Current context is: %s","messagePattern":"Filter: (.+?) can only be applied to arrays\\. Current context is: (.+?)","errorType":"exception","errorClass":"PathNotFoundException","httpStatus":null,"severity":"error","filePath":"json-path/src/main/java/com/jayway/jsonpath/internal/path/ArrayPathToken.java","lineNumber":48,"sourceCode":"     * @return false if current evaluation call must be skipped, true otherwise\n     * @throws PathNotFoundException if model is null and evaluation must be interrupted\n     * @throws InvalidPathException if model is not an array and evaluation must be interrupted\n     */\n    protected boolean checkArrayModel(String currentPath, Object model, EvaluationContextImpl ctx) {\n        if (model == null){\n            if (!isUpstreamDefinite()\n                    || ctx.options().contains(Option.SUPPRESS_EXCEPTIONS)) {\n                return false;\n            } else {\n                throw new PathNotFoundException(\"The path \" + currentPath + \" is null\");\n            }\n        }\n        if (!ctx.jsonProvider().isArray(model)) {\n            if (!isUpstreamDefinite()\n                    || ctx.options().contains(Option.SUPPRESS_EXCEPTIONS)) {\n                return false;\n            } else {\n                throw new PathNotFoundException(format(\"Filter: %s can only be applied to arrays. Current context is: %s\", toString(), model));\n            }\n        }\n        return true;\n    }\n}\n","sourceCodeStart":30,"sourceCodeEnd":54,"githubUrl":"https://github.com/json-path/JsonPath/blob/62a4c9f0f65ba3f625aa0867d64c528ba72d09ec/json-path/src/main/java/com/jayway/jsonpath/internal/path/ArrayPathToken.java#L30-L54","documentation":"JsonPath's filter token `[?(...)]` was evaluated against a JSON model that is not an array (e.g. an object or scalar). The library only applies filters to arrays; when the upstream path is definite (cannot yield multiple results) and exceptions are not suppressed, it throws PathNotFoundException instead of returning nothing. It is thrown from checkArrayModel during path evaluation, not compilation.","triggerScenarios":"Evaluating a path like `$.store[?(@.price < 10)]` where `$.store` resolves to an object or null rather than an array; calling JsonPath.read with a filter on a definite path whose value is a map; compiling with a filter after a property access that returns a single object.","commonSituations":"Document schema drift: an API starts returning a single object where a list used to be; typos in property names resolving to null; forgetting that `$..prop[?(...)]` upstream may be non-array on some documents; users assuming filters work on objects like in jq.","solutions":["Verify the value the filter is applied to is actually a JSON array (inspect with JsonPath.read up to the filter without it).","Wrap the filter target in an array-ifying expression, e.g. `$.items.values()` or use `$[?(@.x)]` only after a wildcard/scan that yields arrays.","Add Option.SUPPRESS_EXCEPTIONS (or Option.ALWAYS_RETURN_LIST) to the Configuration so a non-array context returns empty/null instead of throwing.","If the source data changed shape, update the path to address the array (e.g. `$.store.book[?(...)]` instead of `$.store[?(...)]`)."],"exampleFix":"// before\nList<Map<String,Object>> cheap = JsonPath.read(json, \"$[?(@.price < 10)]\"); // json root is an object\n// after\nList<Map<String,Object>> cheap = JsonPath.read(json, \"$.items[?(@.price < 10)]\");\n// or suppress:\nConfiguration cfg = Configuration.builder().options(Option.SUPPRESS_EXCEPTIONS).build();","handlingStrategy":"validation","validationCode":"Object ctxVal = JsonPath.read(json, \"$.store\");\nif (!(ctxVal instanceof List)) {\n    throw new IllegalArgumentException(\"Filter target '$.store' is not an array: \" + (ctxVal == null ? \"null\" : ctxVal.getClass()));\n}","typeGuard":"boolean isArrayContext(Object model) {\n    return model instanceof java.util.List;\n}","tryCatchPattern":"try {\n    return JsonPath.read(json, \"$.store[?(@.price < 10)]\");\n} catch (PathNotFoundException e) {\n    return java.util.Collections.emptyList();\n}","preventionTips":["Check the shape of the filter target node before appending a filter to the path.","Use Option.SUPPRESS_EXCEPTIONS or Option.ALWAYS_RETURN_LIST for tolerant reads.","Add schema tests that assert list-vs-object shapes for filter targets."],"tags":["json-path","filter","path-not-found","evaluation"],"backgroundTag":"resource-not-found","analyzedSha":"62a4c9f0f65ba3f625aa0867d64c528ba72d09ec","analyzedAt":"2026-09-11T11:36:00.448Z","contentChangedAt":"2026-09-11T11:36:00.448Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}