flowable/flowable-engine · error · FlowableIllegalArgumentException
unavailableAfter is null
Error message
unavailableAfter is null
What it means
planItemInstanceLastUnavailableAfter(Date) on PlanItemInstanceQueryImpl requires a non-null Date and throws FlowableIllegalArgumentException when unavailableAfter is null. The Flowable CMMN query API validates every filter argument eagerly in the builder so that invalid queries fail at construction time instead of producing broken SQL at execution time. Passing null means no meaningful date filter was supplied, so the library refuses the call.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/PlanItemInstanceQueryImpl.java:402
}
@Override
public PlanItemInstanceQuery planItemInstanceLastUnavailableBefore(Date unavailableBefore) {
if (unavailableBefore == null) {
throw new FlowableIllegalArgumentException("unavailableBefore is null");
}
if (inOrStatement) {
this.currentOrQueryObject.lastUnavailableBefore = unavailableBefore;
} else {
this.lastUnavailableBefore = unavailableBefore;
}
return this;
}
@Override
public PlanItemInstanceQuery planItemInstanceLastUnavailableAfter(Date unavailableAfter) {
if (unavailableAfter == null) {
throw new FlowableIllegalArgumentException("unavailableAfter is null");
}
if (inOrStatement) {
this.currentOrQueryObject.lastUnavailableAfter = unavailableAfter;
} else {
this.lastUnavailableAfter = unavailableAfter;
}
return this;
}
@Override
public PlanItemInstanceQuery planItemInstanceLastEnabledBefore(Date enabledBefore) {
if (enabledBefore == null) {
throw new FlowableIllegalArgumentException("enabledBefore is null");
}
if (inOrStatement) {
this.currentOrQueryObject.lastEnabledBefore = enabledBefore;
} else {
this.lastEnabledBefore = enabledBefore;View on GitHub (pinned to d6d39ce1c6)
Solutions
- Ensure a non-null Date is passed, e.g. planItemInstanceLastUnavailableAfter(new Date()) or a parsed value.
- Skip calling planItemInstanceLastUnavailableAfter entirely when the filter is not provided (conditional builder chaining).
- Default the value at the caller boundary, e.g. Optional.ofNullable(request.getUnavailableAfter()).orElse(defaultDate).
- Catch FlowableIllegalArgumentException if null is an acceptable input and fall back to an unfiltered query.
Example fix
// before
query.planItemInstanceLastUnavailableAfter(request.getUnavailableAfter()); // NPE-ish throw when null
// after
if (request.getUnavailableAfter() != null) {
query.planItemInstanceLastUnavailableAfter(request.getUnavailableAfter());
} Defensive patterns
Strategy: validation
Validate before calling
if (unavailableAfter == null) {
throw new IllegalArgumentException("unavailableAfter filter requires a non-null Date; omit the filter instead");
}
query.planItemInstanceLastUnavailableAfter(unavailableAfter); Type guard
boolean hasFilter(Date d) { return d != null; } Try / catch
try {
query.planItemInstanceLastUnavailableAfter(date);
} catch (FlowableIllegalArgumentException e) {
// rebuild query without the unavailableAfter filter
query = cmmnRuntimeService.createPlanItemInstanceQuery();
} Prevention
- Never pass optional filter Dates straight from DTOs into query builders without a null check
- Use conditional builder chaining helpers for optional filters
- Add unit tests covering null filter arguments
- Normalize optional timestamps with Optional.ofNullable(...).orElse(default)
When it happens
Trigger: Calling createPlanItemInstanceQuery().planItemInstanceLastUnavailableAfter(null), typically when the date is the result of an uninitialized/unassigned variable or an unpopulated request parameter that was passed straight into the query builder.
Common situations: REST/search endpoints where the client omits an 'unavailableAfter' filter and the handler passes the null parsed value into the builder; bean/form binding leaving the Date field null; refactors that changed a default date to null; OR-statement code paths reusing an unset variable.
Related errors
- variableNames is null or empty
- planItemDefinitionId is null
- planItemDefinitionIds is null
- involvedUser is null
- userId is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/0cb3f1b2ab99b148.
Report an issue: GitHub.