flowable/flowable-engine · error · FlowableIllegalArgumentException

Provided plan item instance id is null

Error message

Provided plan item instance id is null

What it means

SuspendedJobQueryImpl.planItemInstanceId(String) throws FlowableIllegalArgumentException when the given planItemInstanceId is null. The Flowable query API validates required filter values eagerly at setter time so that malformed queries fail immediately rather than producing confusing empty results or SQL errors at query execution. A null plan item instance id is never a meaningful filter, so it is rejected outright.

Solutions

  1. Ensure the plan item instance id is resolved correctly before building the query (e.g. via a plan item instance lookup or runtime service call).
  2. Guard the setter call: only call planItemInstanceId(...) when the id is non-null, otherwise omit the filter entirely.
  3. If the id should always exist, fix upstream data flow so the variable holding the id is populated (check API payload, DB record, or process variable).

Example fix

// before
query.planItemInstanceId(request.getPlanItemInstanceId()); // NPE-ish throw when null
// after
String planItemInstanceId = request.getPlanItemInstanceId();
if (planItemInstanceId != null) {
    query.planItemInstanceId(planItemInstanceId);
}
Defensive patterns

Strategy: validation

Validate before calling

if (planItemInstanceId == null || planItemInstanceId.isEmpty()) {
    throw new IllegalArgumentException("planItemInstanceId must be provided before querying suspended jobs");
}

Type guard

boolean hasPlanItemInstanceId(String id) { return id != null && !id.isEmpty(); }

Try / catch

try {
    jobService.createSuspendedJobQuery().planItemInstanceId(id).singleResult();
} catch (FlowableIllegalArgumentException e) {
    // treat as 'no filter value provided' and fall back to a broader query
}

Prevention

When it happens

Trigger: Calling new SuspendedJobQueryImpl(...).planItemInstanceId(null), or passing a variable/parameter that was never initialized (e.g. a CMMN plan item id resolved from a map or request param that is absent) directly into planItemInstanceId().

Common situations: Developers building dynamic suspended-job queries in CMMN scenarios where the plan item instance id comes from user input, a case instance lookup, or an optional API field; the value is null because the case/plan item was not yet created or the wrong key was used to look it up.

Related errors


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

Appendix: source

Thrown at modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/SuspendedJobQueryImpl.java:360

    }

    @Override
    public SuspendedJobQueryImpl caseDefinitionKey(String caseDefinitionKey) {
        if (caseDefinitionKey == null) {
            throw new FlowableIllegalArgumentException("Provided case definition key is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.caseDefinitionKey = caseDefinitionKey;
        } else {
            this.caseDefinitionKey = caseDefinitionKey;
        }
        return this;
    }
    
    @Override
    public SuspendedJobQueryImpl planItemInstanceId(String planItemInstanceId) {
        if (planItemInstanceId == null) {
            throw new FlowableIllegalArgumentException("Provided plan item instance id is null");
        }
        subScopeId(planItemInstanceId);
        scopeType(ScopeTypes.CMMN);
        return this;
    }

    @Override
    public SuspendedJobQueryImpl correlationId(String correlationId) {
        if (correlationId == null) {
            throw new FlowableIllegalArgumentException("Provided correlationId is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.correlationId = correlationId;
        } else {
            this.correlationId = correlationId;
        }
        return this;
    }

View on GitHub (pinned to d6d39ce1c6)