flowable/flowable-engine · error · FlowableIllegalArgumentException

before time is null

Error message

before time is null

What it means

HistoricCaseInstanceQueryImpl.finishedBefore() throws FlowableIllegalArgumentException when the beforeTime Date is null. The timestamp is used in a finished-time <= comparison in the generated SQL, so Flowable validates non-null before storing it on the query or the current or-query object.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/history/HistoricCaseInstanceQueryImpl.java:595

            this.finished = true;
        }
        return this;
    }
    
    @Override
    public HistoricCaseInstanceQueryImpl unfinished() {
        if (inOrStatement) {
            this.currentOrQueryObject.unfinished = true;
        } else {
            this.unfinished = true;
        }
        return this;
    }
    
    @Override
    public HistoricCaseInstanceQueryImpl finishedBefore(Date beforeTime) {
        if (beforeTime == null) {
            throw new FlowableIllegalArgumentException("before time is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.finishedBefore = beforeTime;
        } else {
            this.finishedBefore = beforeTime;
        }
        return this;
    }
    
    @Override
    public HistoricCaseInstanceQueryImpl finishedAfter(Date afterTime) {
        if (afterTime == null) {
            throw new FlowableIllegalArgumentException("after time is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.finishedAfter = afterTime;
        } else {
            this.finishedAfter = afterTime;

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Pass a parsed non-null Date, e.g. finishedBefore(Date.from(instant)).
  2. Only call finishedBefore when the end bound is present; otherwise skip it.
  3. Validate/parse dates explicitly and fail with a clear format error instead of passing null through.
  4. Catch FlowableIllegalArgumentException to return a validation message about the required date bound.

Example fix

// before
query.finishedBefore(endDate);
// after
if (endDate != null) {
    query.finishedBefore(endDate);
}
Defensive patterns

Strategy: validation

Validate before calling

if (beforeTime != null) {
    query.finishedBefore(beforeTime);
}

Type guard

boolean hasDate(Date d) {
    return d != null;
}

Try / catch

try {
    query.finishedBefore(beforeTime);
} catch (FlowableIllegalArgumentException e) {
    throw new InvalidRequestException("finishedBefore date is required");
}

Prevention

When it happens

Trigger: Calling finishedBefore(null), e.g. when the 'finished before' bound comes from an optional date-range filter whose end bound was not supplied, or from a date parser that returned null on unparseable input.

Common situations: Date-range report UIs where only 'finishedAfter' was filled in; the code calls both bound setters regardless. Also occurs after SimpleDateFormat/DateTimeFormatter failures silently yield null.

Related errors


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