{"record":{"id":"0cb3f1b2ab99b148","repo":"flowable/flowable-engine","slug":"unavailableafter-is-null","errorCode":null,"errorMessage":"unavailableAfter is null","messagePattern":"unavailableAfter 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":402,"sourceCode":"    }\n\n    @Override\n    public PlanItemInstanceQuery planItemInstanceLastUnavailableBefore(Date unavailableBefore) {\n        if (unavailableBefore == null) {\n            throw new FlowableIllegalArgumentException(\"unavailableBefore is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.lastUnavailableBefore = unavailableBefore;\n        } else {\n            this.lastUnavailableBefore = unavailableBefore;\n        }\n        return this;\n    }\n\n    @Override\n    public PlanItemInstanceQuery planItemInstanceLastUnavailableAfter(Date unavailableAfter) {\n        if (unavailableAfter == null) {\n            throw new FlowableIllegalArgumentException(\"unavailableAfter is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.lastUnavailableAfter = unavailableAfter;\n        } else {\n            this.lastUnavailableAfter = unavailableAfter;\n        }\n        return this;\n    }\n\n    @Override\n    public PlanItemInstanceQuery planItemInstanceLastEnabledBefore(Date enabledBefore) {\n        if (enabledBefore == null) {\n            throw new FlowableIllegalArgumentException(\"enabledBefore is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.lastEnabledBefore = enabledBefore;\n        } else {\n            this.lastEnabledBefore = enabledBefore;","sourceCodeStart":384,"sourceCodeEnd":420,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/PlanItemInstanceQueryImpl.java#L384-L420","documentation":"planItemInstanceLastUnavailableAfter(Date) on PlanItemInstanceQueryImpl requires a non-null Date and throws FlowableIllegalArgumentException when unavailableAfter is null. The Flowable CMMN query API validates every filter argument eagerly in the builder so that invalid queries fail at construction time instead of producing broken SQL at execution time. Passing null means no meaningful date filter was supplied, so the library refuses the call.","triggerScenarios":"Calling createPlanItemInstanceQuery().planItemInstanceLastUnavailableAfter(null), typically when the date is the result of an uninitialized/unassigned variable or an unpopulated request parameter that was passed straight into the query builder.","commonSituations":"REST/search endpoints where the client omits an 'unavailableAfter' filter and the handler passes the null parsed value into the builder; bean/form binding leaving the Date field null; refactors that changed a default date to null; OR-statement code paths reusing an unset variable.","solutions":["Ensure a non-null Date is passed, e.g. planItemInstanceLastUnavailableAfter(new Date()) or a parsed value.","Skip calling planItemInstanceLastUnavailableAfter entirely when the filter is not provided (conditional builder chaining).","Default the value at the caller boundary, e.g. Optional.ofNullable(request.getUnavailableAfter()).orElse(defaultDate).","Catch FlowableIllegalArgumentException if null is an acceptable input and fall back to an unfiltered query."],"exampleFix":"// before\nquery.planItemInstanceLastUnavailableAfter(request.getUnavailableAfter()); // NPE-ish throw when null\n// after\nif (request.getUnavailableAfter() != null) {\n    query.planItemInstanceLastUnavailableAfter(request.getUnavailableAfter());\n}","handlingStrategy":"validation","validationCode":"if (unavailableAfter == null) {\n    throw new IllegalArgumentException(\"unavailableAfter filter requires a non-null Date; omit the filter instead\");\n}\nquery.planItemInstanceLastUnavailableAfter(unavailableAfter);","typeGuard":"boolean hasFilter(Date d) { return d != null; }","tryCatchPattern":"try {\n    query.planItemInstanceLastUnavailableAfter(date);\n} catch (FlowableIllegalArgumentException e) {\n    // rebuild query without the unavailableAfter filter\n    query = cmmnRuntimeService.createPlanItemInstanceQuery();\n}","preventionTips":["Never pass optional filter Dates straight from DTOs into query builders without a null check","Use conditional builder chaining helpers for optional filters","Add unit tests covering null filter arguments","Normalize optional timestamps with Optional.ofNullable(...).orElse(default)"],"tags":["java","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-14T05:17:10.506Z"}