flowable/flowable-engine · error · FlowableIllegalArgumentException
before time is null
Error message
before time is null
What it means
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.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/ExecutionQueryImpl.java:935
return this;
}
@Override
public ExecutionQuery withLocalizationFallback() {
if (inOrStatement) {
currentOrQueryObject.withLocalizationFallback = true;
} else {
this.withLocalizationFallback = true;
}
return this;
}
@Override
public ExecutionQuery startedBefore(Date beforeTime) {
if (beforeTime == null) {
throw new FlowableIllegalArgumentException("before time is null");
}
if (inOrStatement) {
currentOrQueryObject.startedBefore = beforeTime;
} else {
this.startedBefore = beforeTime;
}
return this;
}
@Override
public ExecutionQuery startedAfter(Date afterTime) {
if (afterTime == null) {
throw new FlowableIllegalArgumentException("after time is null");
}
if (inOrStatement) {View on GitHub (pinned to d6d39ce1c6)
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
Example fix
// before
query.startedBefore(reportFilter.getEndDate()); // throws when null (unbounded range)
// after
if (reportFilter.getEndDate() != null) {
query.startedBefore(reportFilter.getEndDate());
} Defensive patterns
Strategy: validation
Validate before calling
if (endDate != null) { query.startedBefore(endDate); } Type guard
boolean hasDateBoundary(Date d) { return d != null; } Try / catch
try {
query.startedBefore(endDate);
} catch (org.flowable.common.engine.api.FlowableIllegalArgumentException e) {
log.warn("start-before boundary missing; time filter skipped");
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Case definition version is null
- Case instance id is null
- Case instance ids is null
- Business key is null
- rootScopeId is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/f776d40d0af94c88.
Report an issue: GitHub.