flowable/flowable-engine · error · FlowableIllegalArgumentException
enabledBefore is null
Error message
enabledBefore is null
What it means
planItemInstanceLastEnabledBefore(Date) validates that enabledBefore is non-null and throws FlowableIllegalArgumentException otherwise. Like all Flowable CMMN query filters, the check happens in the builder method so bad queries fail fast at construction. A null Date cannot be translated into a SQL comparison, so it is rejected.
Solutions
- Pass a valid Date, e.g. planItemInstanceLastEnabledBefore(someParsedDate).
- Guard the call: only invoke the method when the date is non-null.
- Normalize optional input with Optional.ofNullable(...).orElse(default) before building the query.
- Wrap in try-catch for FlowableIllegalArgumentException and build the query without the filter.
Example fix
// before
query.planItemInstanceLastEnabledBefore(null);
// after
Date enabledBefore = parseDate(request.getEnabledBefore());
if (enabledBefore != null) {
query.planItemInstanceLastEnabledBefore(enabledBefore);
} Defensive patterns
Strategy: validation
Validate before calling
if (enabledBefore == null) {
throw new IllegalArgumentException("enabledBefore must be non-null");
}
query.planItemInstanceLastEnabledBefore(enabledBefore); Type guard
boolean isUsableDate(Date d) { return d != null; } Try / catch
try {
query.planItemInstanceLastEnabledBefore(enabledBefore);
} catch (FlowableIllegalArgumentException e) {
query = cmmnRuntimeService.createPlanItemInstanceQuery();
} Prevention
- Validate optional filter inputs before constructing the query
- Skip filters that have no value instead of passing null
- Keep DTO-to-query mapping code null-aware
- Test all query builder calls with missing filter values
When it happens
Trigger: Calling createPlanItemInstanceQuery().planItemInstanceLastEnabledBefore(null), usually from an unassigned Date field, an absent request parameter, or a mapping layer that produced null.
Common situations: Dashboard/search forms where the 'enabledBefore' filter is optional and the null value is forwarded unchanged; deserialization of JSON payloads missing the date field; unit tests passing null to check behavior.
Related errors
- activatedBefore is null
- completedBefore is null
- disabledAfter is null
- disabledBefore is null
- enabledAfter is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/3760717b35216e1e.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/PlanItemInstanceQueryImpl.java:415
}
@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;
}
return this;
}
@Override
public PlanItemInstanceQuery planItemInstanceLastEnabledAfter(Date enabledAfter) {
if (enabledAfter == null) {
throw new FlowableIllegalArgumentException("enabledAfter is null");
}
if (inOrStatement) {
this.currentOrQueryObject.lastEnabledAfter = enabledAfter;
} else {
this.lastEnabledAfter = enabledAfter;View on GitHub (pinned to d6d39ce1c6)