{"record":{"id":"ec9911bef20e89ee","repo":"flowable/flowable-engine","slug":"completedafter-is-null","errorCode":null,"errorMessage":"completedAfter is null","messagePattern":"completedAfter 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":532,"sourceCode":"    }\n\n    @Override\n    public PlanItemInstanceQuery planItemInstanceCompletedBefore(Date completedBefore) {\n        if (completedBefore == null) {\n            throw new FlowableIllegalArgumentException(\"completedBefore is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.completedBefore = completedBefore;\n        } else {\n            this.completedBefore = completedBefore;\n        }\n        return this;\n    }\n\n    @Override\n    public PlanItemInstanceQuery planItemInstanceCompletedAfter(Date completedAfter) {\n        if (completedAfter == null) {\n            throw new FlowableIllegalArgumentException(\"completedAfter is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.completedAfter = completedAfter;\n        } else {\n            this.completedAfter = completedAfter;\n        }\n        return this;\n    }\n\n    @Override\n    public PlanItemInstanceQuery planItemInstanceOccurredBefore(Date occurredBefore) {\n        if (occurredBefore == null) {\n            throw new FlowableIllegalArgumentException(\"occurredBefore is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.occurredBefore = occurredBefore;\n        } else {\n            this.occurredBefore = occurredBefore;","sourceCodeStart":514,"sourceCodeEnd":550,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/PlanItemInstanceQueryImpl.java#L514-L550","documentation":"Flowable throws FlowableIllegalArgumentException when planItemInstanceCompletedAfter(Date) is called with a null Date argument. Query parameter methods validate their inputs eagerly so an invalid query fails at construction time rather than producing a broken SQL query or silent wrong results. Passing null means the caller has no completedAfter timestamp to filter on and should simply not call the method.","triggerScenarios":"Calling runtimeService.createPlanItemInstanceQuery().planItemInstanceCompletedAfter(null), typically when the date comes from an optional request parameter or deserialized DTO field that was not set.","commonSituations":"REST/UI layer passes through an unvalidated 'completedAfter' query param that is absent or null; a Java bean built from JSON where the field was omitted; a default-initialization bug where a Calendar/Date conversion returned null.","solutions":["Ensure a non-null Date is passed: resolve the value from user input or compute a default before calling planItemInstanceCompletedAfter.","Only call the method when the value exists (null-check at the call site); omitting the call means no filter on this attribute.","If input is a string, parse it with a checked date parser and reject invalid/empty input before building the query.","Wrap the query-building code in a try-catch for FlowableIllegalArgumentException to fail fast with a clear client-facing message."],"exampleFix":"// before\nDate completedAfter = params.get(\"completedAfter\"); // may be null\nquery.planItemInstanceCompletedAfter(completedAfter);\n// after\nDate completedAfter = params.get(\"completedAfter\");\nif (completedAfter != null) {\n    query.planItemInstanceCompletedAfter(completedAfter);\n}","handlingStrategy":"validation","validationCode":"if (completedAfter == null) {\n    throw new IllegalArgumentException(\"completedAfter must be provided or the filter must be omitted\");\n}\nquery.planItemInstanceCompletedAfter(completedAfter);","typeGuard":"boolean hasCompletedAfter = (completedAfter != null);","tryCatchPattern":"try {\n    query.planItemInstanceCompletedAfter(completedAfter);\n} catch (FlowableIllegalArgumentException e) {\n    if (e.getMessage().contains(\"completedAfter\")) {\n        throw new BadRequestException(\"completedAfter date filter must not be null\");\n    }\n    throw e;\n}","preventionTips":["Null-check optional dates at the call site and conditionally apply query criteria","Validate/parse user-supplied date strings before building queries","Use Optional<Date> in your service layer to make absence explicit","Centralize query building in a helper that only applies non-null filters"],"tags":["java","flowable","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"}