flowable/flowable-engine · error · FlowableIllegalArgumentException
startedAfter is null
Error message
startedAfter is null
What it means
planItemInstanceLastStartedAfter(Date) throws FlowableIllegalArgumentException 'startedAfter is null' when the argument is null. Like all date filters in PlanItemInstanceQueryImpl, null is rejected eagerly in the builder because it cannot produce a valid SQL bound. The filter must be a concrete Date or simply not applied.
Solutions
- Supply a valid Date instance.
- Apply the filter conditionally only when the value is non-null.
- Default the value at the API boundary before query construction.
- Catch FlowableIllegalArgumentException and fall back to a query without the filter.
Example fix
// before
query.planItemInstanceLastStartedAfter(range.getStart()); // may be null
// after
if (range.getStart() != null) {
query.planItemInstanceLastStartedAfter(range.getStart());
} Defensive patterns
Strategy: validation
Validate before calling
if (startedAfter == null) {
throw new IllegalArgumentException("startedAfter must be a non-null Date");
}
query.planItemInstanceLastStartedAfter(startedAfter); Type guard
boolean boundPresent(Date d) { return d != null; } Try / catch
try {
query.planItemInstanceLastStartedAfter(startedAfter);
} catch (FlowableIllegalArgumentException e) {
query = cmmnRuntimeService.createPlanItemInstanceQuery();
} Prevention
- Null-check date range bounds before query construction
- Skip absent bounds rather than passing null
- Compute report period bounds defensively
- Include null-filter cases in test suites
When it happens
Trigger: Calling planItemInstanceLastStartedAfter(null), e.g. when a report period's start bound was never computed or a request field was omitted.
Common situations: Time-range report builders with optional bounds; null from date-range parsing of user input; microservice payloads missing the field; tests invoking builders with null to verify validation.
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/ea9042bfa4bc2b93.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/PlanItemInstanceQueryImpl.java:480
}
@Override
public PlanItemInstanceQuery planItemInstanceLastStartedBefore(Date startedBefore) {
if (startedBefore == null) {
throw new FlowableIllegalArgumentException("activatedBefore is null");
}
if (inOrStatement) {
this.currentOrQueryObject.lastStartedBefore = startedBefore;
} else {
this.lastStartedBefore = startedBefore;
}
return this;
}
@Override
public PlanItemInstanceQuery planItemInstanceLastStartedAfter(Date startedAfter) {
if (startedAfter == null) {
throw new FlowableIllegalArgumentException("startedAfter is null");
}
if (inOrStatement) {
this.currentOrQueryObject.lastStartedAfter = startedAfter;
} else {
this.lastStartedAfter = startedAfter;
}
return this;
}
@Override
public PlanItemInstanceQuery planItemInstanceLastSuspendedBefore(Date suspendedBefore) {
if (suspendedBefore == null) {
throw new FlowableIllegalArgumentException("suspendedBefore is null");
}
if (inOrStatement) {
this.currentOrQueryObject.lastSuspendedBefore = suspendedBefore;
} else {
this.lastSuspendedBefore = suspendedBefore;View on GitHub (pinned to d6d39ce1c6)