{"record":{"id":"f776d40d0af94c88","repo":"flowable/flowable-engine","slug":"before-time-is-null-f776d4","errorCode":null,"errorMessage":"before time is null","messagePattern":"before time is null","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/ExecutionQueryImpl.java","lineNumber":935,"sourceCode":"        \n        return this;\n    }\n\n    @Override\n    public ExecutionQuery withLocalizationFallback() {\n        if (inOrStatement) {\n            currentOrQueryObject.withLocalizationFallback = true;\n        } else {\n            this.withLocalizationFallback = true;\n        }\n        \n        return this;\n    }\n\n    @Override\n    public ExecutionQuery startedBefore(Date beforeTime) {\n        if (beforeTime == null) {\n            throw new FlowableIllegalArgumentException(\"before time is null\");\n        }\n        \n        if (inOrStatement) {\n            currentOrQueryObject.startedBefore = beforeTime;\n        } else {\n            this.startedBefore = beforeTime;\n        }\n        \n        return this;\n    }\n\n    @Override\n    public ExecutionQuery startedAfter(Date afterTime) {\n        if (afterTime == null) {\n            throw new FlowableIllegalArgumentException(\"after time is null\");\n        }\n        \n        if (inOrStatement) {","sourceCodeStart":917,"sourceCodeEnd":953,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/ExecutionQueryImpl.java#L917-L953","documentation":"startedBefore(Date) restricts the query to executions started before the given instant. Flowable throws FlowableIllegalArgumentException 'before time is null' when the Date argument is null, because the timestamp comparison predicate cannot be built from null.","triggerScenarios":"Calling executionQuery.startedBefore(null), e.g. when a date range filter has an unbounded start side represented as null, or a date parser returned null for invalid input.","commonSituations":"Dashboard/report queries with optional time-window filters (from/to dates); SimpleDateFormat/DateTimeFormatter parsing failures returning null; REST query params for dates omitted by clients.","solutions":["Pass a non-null java.util.Date, e.g. startedBefore(new Date(System.currentTimeMillis()))","Only apply startedBefore() when the boundary date is present; omit it for an unbounded range","Fix date parsing: return a parse error instead of null when converting user input","Consider startedBefore(Date.from(instant)) when working with the java.time API to avoid null conversion"],"exampleFix":"// before\nquery.startedBefore(reportFilter.getEndDate()); // throws when null (unbounded range)\n// after\nif (reportFilter.getEndDate() != null) {\n    query.startedBefore(reportFilter.getEndDate());\n}","handlingStrategy":"validation","validationCode":"if (endDate != null) { query.startedBefore(endDate); }","typeGuard":"boolean hasDateBoundary(Date d) { return d != null; }","tryCatchPattern":"try {\n    query.startedBefore(endDate);\n} catch (org.flowable.common.engine.api.FlowableIllegalArgumentException e) {\n    log.warn(\"start-before boundary missing; time filter skipped\");\n}","preventionTips":["Represent unbounded time ranges by omitting the filter, not passing null","Handle date-parsing errors explicitly instead of propagating null Dates","Prefer java.time and convert with Date.from(...) which is non-null or throws","Apply range filters through a helper that checks both boundaries"],"tags":["flowable","query-validation","date-filter","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-14T16:17:12.679Z"}