flowable/flowable-engine · error · FlowableIllegalArgumentException

availableBefore is null

Error message

availableBefore is null

What it means

Thrown by PlanItemInstanceQueryImpl.planItemInstanceLastAvailableBefore when the availableBefore Date is null. This filter bounds the last time a plan item was available; the builder rejects a null bound immediately.

Solutions

  1. Pass a valid java.util.Date for the bound.
  2. Skip the call when no upper bound is desired.
  3. Validate date inputs at the API boundary before constructing the query.

Example fix

// before
query.planItemInstanceLastAvailableBefore(to); // to may be null
// after
if (to != null) {
    query.planItemInstanceLastAvailableBefore(to);
}
Defensive patterns

Strategy: validation

Validate before calling

if (availableBefore != null) {
    planItemInstanceQuery.planItemInstanceLastAvailableBefore(availableBefore);
}

Type guard

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

Try / catch

try {
    query.planItemInstanceLastAvailableBefore(availableBefore);
} catch (FlowableIllegalArgumentException e) {
    if (e.getMessage().contains("availableBefore is null")) {
        // skip the filter or return a 400 to the client
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling planItemInstanceLastAvailableBefore(null), e.g. with a nullable timestamp from an upstream service or request.

Common situations: Dashboard time-range filters where the end bound is optional; a null from a date-conversion utility for malformed input.

Related errors


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

Appendix: source

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

    }

    @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;
        }
        return this;
    }

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

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

View on GitHub (pinned to d6d39ce1c6)