{"record":{"id":"e6736c04f4d4fbda","repo":"json-path/JsonPath","slug":"expected-null-node","errorCode":null,"errorMessage":"Expected null node","messagePattern":"Expected null node","errorType":"exception","errorClass":"InvalidPathException","httpStatus":null,"severity":"error","filePath":"json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java","lineNumber":88,"sourceCode":"\n    public PredicateNode asPredicateNode() {\n        throw new InvalidPathException(\"Expected predicate node\");\n    }\n\n    public boolean isValueListNode() {\n        return false;\n    }\n\n    public ValueListNode asValueListNode() {\n        throw new InvalidPathException(\"Expected value list node\");\n    }\n\n    public boolean isNullNode() {\n        return false;\n    }\n\n    public NullNode asNullNode() {\n        throw new InvalidPathException(\"Expected null node\");\n    }\n\n    public UndefinedNode asUndefinedNode() {\n        throw new InvalidPathException(\"Expected undefined node\");\n    }\n\n    public boolean isUndefinedNode() {\n        return false;\n    }\n\n    public boolean isClassNode() {\n        return false;\n    }\n\n    public ClassNode asClassNode() {\n        throw new InvalidPathException(\"Expected class node\");\n    }\n","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/json-path/JsonPath/blob/62a4c9f0f65ba3f625aa0867d64c528ba72d09ec/json-path/src/main/java/com/jayway/jsonpath/internal/filter/ValueNode.java#L70-L106","documentation":"ValueNode's base asNullNode() throws InvalidPathException(\"Expected null node\") when called on a node that is not a NullNode. NullNode represents a JSON null value in filter evaluation; the base-class default throws because only NullNode can be downcast to itself. It surfaces when an operator or path of evaluation requires a null literal but the operand is some other value type.","triggerScenarios":"Filter expressions comparing with null semantics where the node is not null — e.g. type checks/operations in evaluate that require NullNode; calling asNullNode() directly on a StringNode/NumberNode. Note: @.field == null in JsonPath is often handled before this, but custom operators or paths that demand a NullNode operand will hit this.","commonSituations":"Documents where a field checked for null actually holds an empty string, 0, or is missing entirely (undefined), so the operand node is not NullNode; custom filter operators built on the internal API.","solutions":["Use JsonPath's null-check idioms that tolerate missing values, e.g. $.items[?(@.field == null)] and verify the field exists with @.field in filters where needed","Check whether the value is an empty string or 0 rather than null and adjust the comparison accordingly","Normalize the document so intended-null fields are actual JSON null","Catch InvalidPathException around evaluation for null-mismatch cases"],"exampleFix":"// before\n$.items[?(@.name == '')] // intended to find null names; name is real null\n// after\n$.items[?(@.name == null)]","handlingStrategy":"type-guard","validationCode":"Object v = JsonPath.parse(json).read(\"$.item.name\", new Predicate[0]);\nif (v == null && expectNullSentinel) throw new IllegalArgumentException(\"name is missing, not null\");","typeGuard":"static boolean isNullOperand(Object o) { return o == null; }","tryCatchPattern":"try {\n    return JsonPath.parse(json).read(\"$.items[?(@.name == null)]\");\n} catch (InvalidPathException e) {\n    // null-mismatch: handle absent vs empty vs null distinctly\n    return handleNullMismatch(json);\n}","preventionTips":["Distinguish null, empty string, 0, and missing fields in your data model","Write predicates that cover the actual sentinel values used in the document","Serialize intended-null fields as explicit JSON null"],"tags":["jsonpath","filter","type-mismatch","null-node"],"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"}