flowable/flowable-engine · error · FlowableIllegalArgumentException

suspendedBefore is null

Error message

suspendedBefore is null

What it means

planItemInstanceLastSuspendedBefore(Date) requires a non-null suspendedBefore Date and throws FlowableIllegalArgumentException 'suspendedBefore is null' otherwise. The CMMN query builder validates each filter argument so invalid queries fail at construction time. Null cannot be turned into a comparison predicate.

Solutions

  1. Pass a concrete Date (e.g. new Date() or a stored suspension timestamp).
  2. Guard the call with a null check and omit the filter when absent.
  3. Substitute a default boundary date when the value is unknown.
  4. Catch FlowableIllegalArgumentException and rebuild without the suspension filter.

Example fix

// before
query.planItemInstanceLastSuspendedBefore(item.getLastSuspendedTime()); // null if never suspended
// after
if (item.getLastSuspendedTime() != null) {
    query.planItemInstanceLastSuspendedBefore(item.getLastSuspendedTime());
}
Defensive patterns

Strategy: validation

Validate before calling

if (suspendedBefore == null) {
    throw new IllegalArgumentException("suspendedBefore must be a non-null Date");
}
query.planItemInstanceLastSuspendedBefore(suspendedBefore);

Type guard

boolean hasDate(Date d) { return d != null; }

Try / catch

try {
    query.planItemInstanceLastSuspendedBefore(suspendedBefore);
} catch (FlowableIllegalArgumentException e) {
    query = cmmnRuntimeService.createPlanItemInstanceQuery();
}

Prevention

When it happens

Trigger: Calling createPlanItemInstanceQuery().planItemInstanceLastSuspendedBefore(null), typically when suspension timestamps were never tracked or a DTO field is unset.

Common situations: Queries against plan items that were never suspended, where a 'last suspended' lookup yields null; optional filters from REST payloads; refactor renaming local variables leaving null initializers.

Related errors


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

Appendix: source

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

    }

    @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;
        }
        return this;
    }

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

View on GitHub (pinned to d6d39ce1c6)