{"record":{"id":"1e63c3e574e5d163","repo":"flowable/flowable-engine","slug":"endedafter-is-null","errorCode":null,"errorMessage":"endedAfter is null","messagePattern":"endedAfter is null","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/PlanItemInstanceQueryImpl.java","lineNumber":662,"sourceCode":"    }\n\n    @Override\n    public PlanItemInstanceQuery planItemInstanceEndedBefore(Date endedBefore) {\n        if (endedBefore == null) {\n            throw new FlowableIllegalArgumentException(\"endedBefore is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.endedBefore = endedBefore;\n        } else {\n            this.endedBefore = endedBefore;\n        }\n        return this;\n    }\n\n    @Override\n    public PlanItemInstanceQuery planItemInstanceEndedAfter(Date endedAfter) {\n        if (endedAfter == null) {\n            throw new FlowableIllegalArgumentException(\"endedAfter is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.endedAfter = endedAfter;\n        } else {\n            this.endedAfter = endedAfter;\n        }\n        return this;\n    }\n\n    @Override\n    public PlanItemInstanceQuery ended() {\n        if (inOrStatement) {\n            this.currentOrQueryObject.ended = true;\n            includeEnded = true;\n        } else {\n            this.ended = true;\n        }\n        return this;","sourceCodeStart":644,"sourceCodeEnd":680,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/PlanItemInstanceQueryImpl.java#L644-L680","documentation":"Flowable's PlanItemInstanceQueryImpl.planItemInstanceEndedAfter(Date) validates its argument and throws FlowableIllegalArgumentException when a null Date is passed. Query criteria setters in Flowable refuse null because null is not a filterable value; omit the criteria entirely instead of passing null. This fail-fast behavior prevents silently unfiltered or broken SQL queries.","triggerScenarios":"Calling planItemInstanceQuery.planItemInstanceEndedAfter(null) directly, or passing a Date variable that was never initialized (e.g. a method parameter or computed date that resolved to null).","commonSituations":"Developers building dynamic query builders that conditionally populate a Date but pass it unconditionally; parsing user-supplied dates with a parser returning null on failure; nullable fields mapped from REST request bodies.","solutions":["Check the Date for null before calling planItemInstanceEndedAfter and skip the criteria when null","If a null filter means 'all', simply do not add the endedAfter criterion to the query","Verify the date source (parser, DTO field, calculation) actually produced a non-null value","Catch FlowableIllegalArgumentException around query construction if inputs are untrusted"],"exampleFix":"// before\nquery.planItemInstanceEndedAfter(endedAfter); // NPE-ish throw when endedAfter == null\n// after\nif (endedAfter != null) {\n    query.planItemInstanceEndedAfter(endedAfter);\n}","handlingStrategy":"validation","validationCode":"if (endedAfter != null) {\n    query.planItemInstanceEndedAfter(endedAfter);\n}","typeGuard":"boolean hasEndedAfter = (endedAfter instanceof Date);","tryCatchPattern":"try {\n    query.planItemInstanceEndedAfter(endedAfter);\n} catch (FlowableIllegalArgumentException e) {\n    log.warn(\"Ignoring endedAfter filter: {}\", e.getMessage());\n}","preventionTips":["Never pass nullable filter values straight into Flowable query setters; always conditionally chain","Validate/parse dates defensively and skip criteria on parse failure","Wrap dynamic query building in a small helper that adds criteria only for non-null values"],"tags":["flowable","cmmn","query","null-argument"],"backgroundTag":"null-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}