{"record":{"id":"275b5d9914eeb37a","repo":"flowable/flowable-engine","slug":"suspendedbefore-is-null","errorCode":null,"errorMessage":"suspendedBefore is null","messagePattern":"suspendedBefore 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":493,"sourceCode":"    }\n\n    @Override\n    public PlanItemInstanceQuery planItemInstanceLastStartedAfter(Date startedAfter) {\n        if (startedAfter == null) {\n            throw new FlowableIllegalArgumentException(\"startedAfter is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.lastStartedAfter = startedAfter;\n        } else {\n            this.lastStartedAfter = startedAfter;\n        }\n        return this;\n    }\n\n    @Override\n    public PlanItemInstanceQuery planItemInstanceLastSuspendedBefore(Date suspendedBefore) {\n        if (suspendedBefore == null) {\n            throw new FlowableIllegalArgumentException(\"suspendedBefore is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.lastSuspendedBefore = suspendedBefore;\n        } else {\n            this.lastSuspendedBefore = suspendedBefore;\n        }\n        return this;\n    }\n\n    @Override\n    public PlanItemInstanceQuery planItemInstanceLastSuspendedAfter(Date suspendedAfter) {\n        if (suspendedAfter == null) {\n            throw new FlowableIllegalArgumentException(\"suspendedAfter is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.lastSuspendedAfter = suspendedAfter;\n        } else {\n            this.lastSuspendedAfter = suspendedAfter;","sourceCodeStart":475,"sourceCodeEnd":511,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/PlanItemInstanceQueryImpl.java#L475-L511","documentation":"planItemInstanceLastSuspendedBefore(Date) requires a non-null suspendedBefore Date and throws FlowableIllegalArgumentException 'suspendedBefore is null' otherwise. The CMMN query builder validates each filter argument so invalid queries fail at construction time. Null cannot be turned into a comparison predicate.","triggerScenarios":"Calling createPlanItemInstanceQuery().planItemInstanceLastSuspendedBefore(null), typically when suspension timestamps were never tracked or a DTO field is unset.","commonSituations":"Queries against plan items that were never suspended, where a 'last suspended' lookup yields null; optional filters from REST payloads; refactor renaming local variables leaving null initializers.","solutions":["Pass a concrete Date (e.g. new Date() or a stored suspension timestamp).","Guard the call with a null check and omit the filter when absent.","Substitute a default boundary date when the value is unknown.","Catch FlowableIllegalArgumentException and rebuild without the suspension filter."],"exampleFix":"// before\nquery.planItemInstanceLastSuspendedBefore(item.getLastSuspendedTime()); // null if never suspended\n// after\nif (item.getLastSuspendedTime() != null) {\n    query.planItemInstanceLastSuspendedBefore(item.getLastSuspendedTime());\n}","handlingStrategy":"validation","validationCode":"if (suspendedBefore == null) {\n    throw new IllegalArgumentException(\"suspendedBefore must be a non-null Date\");\n}\nquery.planItemInstanceLastSuspendedBefore(suspendedBefore);","typeGuard":"boolean hasDate(Date d) { return d != null; }","tryCatchPattern":"try {\n    query.planItemInstanceLastSuspendedBefore(suspendedBefore);\n} catch (FlowableIllegalArgumentException e) {\n    query = cmmnRuntimeService.createPlanItemInstanceQuery();\n}","preventionTips":["Handle entities that were never suspended (null timestamps) before querying","Null-guard every optional filter call","Avoid forwarding unmapped DTO fields directly into builders","Test suspension filter paths with non-suspended data"],"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-18T11:17:12.947Z"}