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

  1. Pass a non-null java.util.Date, e.g. startedBefore(new Date(System.currentTimeMillis()))
  2. Only apply startedBefore() when the boundary date is present; omit it for an unbounded range
  3. Fix date parsing: return a parse error instead of null when converting user input
  4. 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

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


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/f776d40d0af94c88. Report an issue: GitHub.