flowable/flowable-engine · error · FlowableIllegalArgumentException

failedAfter is null

Error message

failedAfter is null

What it means

Flowable throws FlowableIllegalArgumentException when planItemInstanceFailedAfter(Date) is passed a null Date. The method validates its argument immediately so an invalid query fails at construction rather than at SQL execution. An absent filter should be represented by omitting the call entirely.

Solutions

  1. Resolve a concrete Date before calling the method.
  2. Conditionally invoke it only when a value is present.
  3. Validate/parse input dates explicitly before query construction.
  4. Catch FlowableIllegalArgumentException in query-building code and map it to a validation error response.

Example fix

// before
query.planItemInstanceFailedAfter(parseDate(raw)); // parseDate may return null
// after
Date failedAfter = parseDate(raw);
if (failedAfter != null) {
    query.planItemInstanceFailedAfter(failedAfter);
}
Defensive patterns

Strategy: validation

Validate before calling

if (failedAfter == null) {
    throw new IllegalArgumentException("failedAfter must be non-null; omit the filter instead");
}
query.planItemInstanceFailedAfter(failedAfter);

Type guard

boolean hasFailedAfter = (failedAfter != null);

Try / catch

try {
    query.planItemInstanceFailedAfter(failedAfter);
} catch (FlowableIllegalArgumentException e) {
    if (e.getMessage().contains("failedAfter")) {
        throw new BadRequestException("failedAfter date filter must not be null");
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling createPlanItemInstanceQuery().planItemInstanceFailedAfter(null), commonly when the after-date is sourced from an unset optional parameter or DTO field.

Common situations: Missing 'failedAfter' query parameter in an endpoint; JSON body without the field; null from a failed date conversion.

Related errors


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

Appendix: source

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

    }

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

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

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

View on GitHub (pinned to d6d39ce1c6)