flowable/flowable-engine · error · FlowableIllegalArgumentException

createdBefore is null

Error message

createdBefore is null

What it means

Thrown by PlanItemInstanceQueryImpl.planItemInstanceCreatedBefore when the createdBefore Date is null. The builder validates date-range filters eagerly so the resulting SQL comparison is always well-defined. A null date cannot express a bound and is rejected.

Solutions

  1. Pass a valid java.util.Date for the upper bound.
  2. Only call the method when the date is non-null; pair with planItemInstanceCreatedAfter for a range.
  3. Validate/parse the input date before building the query and fail with a clear message if invalid.

Example fix

// before
query.planItemInstanceCreatedBefore(parseDate(endStr)); // may return null
// after
Date end = parseDate(endStr);
if (end != null) {
    query.planItemInstanceCreatedBefore(end);
}
Defensive patterns

Strategy: validation

Validate before calling

if (createdBefore == null) {
    throw new IllegalArgumentException("createdBefore date is required and must be parsed successfully");
}
planItemInstanceQuery.planItemInstanceCreatedBefore(createdBefore);

Type guard

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

Try / catch

try {
    query.planItemInstanceCreatedBefore(createdBefore);
} catch (FlowableIllegalArgumentException e) {
    if (e.getMessage().contains("createdBefore is null")) {
        // rebuild query without the upper date bound
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling planItemInstanceCreatedBefore(null), typically because the end of a date range was not provided or a date parser returned null.

Common situations: Unparseable date strings handled by returning null instead of throwing; an optional 'createdBefore' request parameter that is absent; timezone/format issues in SimpleDateFormat returning null.

Related errors


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

Appendix: source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/PlanItemInstanceQueryImpl.java:337

    @Override
    public PlanItemInstanceQuery planItemInstanceStateUnavailable() {
        return planItemInstanceState(PlanItemInstanceState.UNAVAILABLE);
    }

    @Override
    public PlanItemInstanceQuery planItemInstanceStateCompleted() {
        return planItemInstanceState(PlanItemInstanceState.COMPLETED);
    }
    
    @Override
    public PlanItemInstanceQuery planItemInstanceStateTerminated() {
        return planItemInstanceState(PlanItemInstanceState.TERMINATED);
    }

    @Override
    public PlanItemInstanceQuery planItemInstanceCreatedBefore(Date createdBefore) {
        if (createdBefore == null) {
            throw new FlowableIllegalArgumentException("createdBefore is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.createdBefore = createdBefore;
        } else {
            this.createdBefore = createdBefore;
        }
        return this;
    }

    @Override
    public PlanItemInstanceQuery planItemInstanceCreatedAfter(Date createdAfter) {
        if (createdAfter == null) {
            throw new FlowableIllegalArgumentException("createdAfter is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.createdAfter = createdAfter;
        } else {
            this.createdAfter = createdAfter;

View on GitHub (pinned to d6d39ce1c6)