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

  1. Pass a valid Date, e.g. planItemInstanceLastEnabledBefore(someParsedDate).
  2. Guard the call: only invoke the method when the date is non-null.
  3. Normalize optional input with Optional.ofNullable(...).orElse(default) before building the query.
  4. 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

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


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)