{"record":{"id":"19b124b80836d0e8","repo":"json-path/JsonPath","slug":"failed-to-evaluate-exists-expression","errorCode":null,"errorMessage":"Failed to evaluate exists expression","messagePattern":"Failed to evaluate exists expression","errorType":"exception","errorClass":"JsonPathException","httpStatus":null,"severity":"error","filePath":"json-path/src/main/java/com/jayway/jsonpath/internal/filter/EvaluatorFactory.java","lineNumber":50,"sourceCode":"        evaluators.put(RelationalOperator.NIN, new NotInEvaluator());\n        evaluators.put(RelationalOperator.ALL, new AllEvaluator());\n        evaluators.put(RelationalOperator.CONTAINS, new ContainsEvaluator());\n        evaluators.put(RelationalOperator.MATCHES, new PredicateMatchEvaluator());\n        evaluators.put(RelationalOperator.TYPE, new TypeEvaluator());\n        evaluators.put(RelationalOperator.SUBSETOF, new SubsetOfEvaluator());\n        evaluators.put(RelationalOperator.ANYOF, new AnyOfEvaluator());\n        evaluators.put(RelationalOperator.NONEOF, new NoneOfEvaluator());\n    }\n\n    public static Evaluator createEvaluator(RelationalOperator operator){\n        return evaluators.get(operator);\n    }\n\n    private static class ExistsEvaluator implements Evaluator {\n        @Override\n        public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {\n            if(!left.isBooleanNode() && !right.isBooleanNode()){\n                throw new JsonPathException(\"Failed to evaluate exists expression\");\n            }\n            return left.asBooleanNode().getBoolean() == right.asBooleanNode().getBoolean();\n        }\n    }\n\n    private static class NotEqualsEvaluator implements Evaluator {\n        @Override\n        public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {\n            return !evaluators.get(RelationalOperator.EQ).evaluate(left, right, ctx);\n        }\n    }\n\n    private static class TypeSafeNotEqualsEvaluator implements Evaluator {\n        @Override\n        public boolean evaluate(ValueNode left, ValueNode right, Predicate.PredicateContext ctx) {\n            return !evaluators.get(RelationalOperator.TSEQ).evaluate(left, right, ctx);\n        }\n    }","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/json-path/JsonPath/blob/62a4c9f0f65ba3f625aa0867d64c528ba72d09ec/json-path/src/main/java/com/jayway/jsonpath/internal/filter/EvaluatorFactory.java#L32-L68","documentation":"The ExistsEvaluator handles the 'exists' filter operator. It requires that at least one side of the comparison is a boolean ValueNode; when neither the left nor the right operand is a boolean node it cannot perform the exists comparison and throws JsonPathException with this message. In practice it means the filter expression's operand types don't fit the exists operator.","triggerScenarios":"Using a filter predicate like $.book[?(@.isbn exists true)] (or similar exists/not-exists style expressions in Filter API) where the operands were parsed as non-boolean ValueNodes — e.g. writing 'exists' comparisons against string/number literals, or composing ValueNode-based criteria where neither side is a PathNode evaluated to boolean.","commonSituations":"Hand-writing filter strings with the exists operator against fields whose values are strings or numbers; migrating filter syntax between JsonPath versions where exists semantics changed; building Criteria programmatically and passing non-boolean operands to an exists-style evaluation.","solutions":["Rewrite the filter so exists checks a path against a boolean, e.g. ?(@.isbn exists true) or simply use ?(@.isbn) / ?(@.isbn != null) for presence checks.","Use Criteria API: Criteria.where(\"isbn\").exists(true) (or ne(null)) instead of hand-built operand nodes.","Verify the ValueNode types you pass if using the internal filter/Evaluator API directly; wrap operands with ValueNode.createBooleanNode."],"exampleFix":"// before\nFilter f = filter(where(\"price\").exists(\"yes\")); // neither side boolean -> JsonPathException\n// after\nFilter f = filter(where(\"price\").exists(true));\n// or for presence checks:\nFilter f2 = filter(where(\"price\").ne(null));","handlingStrategy":"type-guard","validationCode":"// ensure exists operands are boolean\nif (!(leftNode instanceof BooleanNode) && !(rightNode instanceof BooleanNode)) {\n    throw new IllegalArgumentException(\"exists operator requires a boolean operand\");\n}","typeGuard":"static boolean isBooleanNode(ValueNode n) {\n    return n != null && n.isBooleanNode();\n}","tryCatchPattern":"try {\n    return filter(where(field).exists(true)).eval(ctx);\n} catch (JsonPathException e) {\n    if (\"Failed to evaluate exists expression\".equals(e.getMessage())) {\n        return filter(where(field).ne(null)).eval(ctx);\n    }\n    throw e;\n}","preventionTips":["Always pair the exists operator with a boolean literal (true/false).","Prefer the Criteria API (.exists(true), .ne(null)) over hand-built filter strings.","Check JsonPath version notes: exists semantics differ across releases."],"tags":["json-path","filter-evaluation","exists-operator","type-mismatch"],"backgroundTag":"type-mismatch","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"}