flowable/flowable-engine · error · FlowableIllegalArgumentException
endedAfter is null
Error message
endedAfter is null
What it means
Flowable's PlanItemInstanceQueryImpl.planItemInstanceEndedAfter(Date) validates its argument and throws FlowableIllegalArgumentException when a null Date is passed. Query criteria setters in Flowable refuse null because null is not a filterable value; omit the criteria entirely instead of passing null. This fail-fast behavior prevents silently unfiltered or broken SQL queries.
Solutions
- Check the Date for null before calling planItemInstanceEndedAfter and skip the criteria when null
- If a null filter means 'all', simply do not add the endedAfter criterion to the query
- Verify the date source (parser, DTO field, calculation) actually produced a non-null value
- Catch FlowableIllegalArgumentException around query construction if inputs are untrusted
Example fix
// before
query.planItemInstanceEndedAfter(endedAfter); // NPE-ish throw when endedAfter == null
// after
if (endedAfter != null) {
query.planItemInstanceEndedAfter(endedAfter);
} Defensive patterns
Strategy: validation
Validate before calling
if (endedAfter != null) {
query.planItemInstanceEndedAfter(endedAfter);
} Type guard
boolean hasEndedAfter = (endedAfter instanceof Date);
Try / catch
try {
query.planItemInstanceEndedAfter(endedAfter);
} catch (FlowableIllegalArgumentException e) {
log.warn("Ignoring endedAfter filter: {}", e.getMessage());
} Prevention
- Never pass nullable filter values straight into Flowable query setters; always conditionally chain
- Validate/parse dates defensively and skip criteria on parse failure
- Wrap dynamic query building in a small helper that adds criteria only for non-null values
When it happens
Trigger: Calling planItemInstanceQuery.planItemInstanceEndedAfter(null) directly, or passing a Date variable that was never initialized (e.g. a method parameter or computed date that resolved to null).
Common situations: Developers building dynamic query builders that conditionally populate a Date but pass it unconditionally; parsing user-supplied dates with a parser returning null on failure; nullable fields mapped from REST request bodies.
Related errors
- activatedBefore is null
- assignee is null
- availableAfter is null
- availableBefore is null
- before time is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/1e63c3e574e5d163.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/PlanItemInstanceQueryImpl.java:662
}
@Override
public PlanItemInstanceQuery planItemInstanceEndedBefore(Date endedBefore) {
if (endedBefore == null) {
throw new FlowableIllegalArgumentException("endedBefore is null");
}
if (inOrStatement) {
this.currentOrQueryObject.endedBefore = endedBefore;
} else {
this.endedBefore = endedBefore;
}
return this;
}
@Override
public PlanItemInstanceQuery planItemInstanceEndedAfter(Date endedAfter) {
if (endedAfter == null) {
throw new FlowableIllegalArgumentException("endedAfter is null");
}
if (inOrStatement) {
this.currentOrQueryObject.endedAfter = endedAfter;
} else {
this.endedAfter = endedAfter;
}
return this;
}
@Override
public PlanItemInstanceQuery ended() {
if (inOrStatement) {
this.currentOrQueryObject.ended = true;
includeEnded = true;
} else {
this.ended = true;
}
return this;View on GitHub (pinned to d6d39ce1c6)