flowable/flowable-engine · error · FlowableIllegalArgumentException

Set of process instance ids is empty

Error message

Set of process instance ids is empty

What it means

ExecutionQueryImpl.processInstanceIds(Set<String>) also rejects an empty set with FlowableIllegalArgumentException("Set of process instance ids is empty"), because an IN () clause with no values is invalid SQL. The library forces callers to make an explicit decision when there is nothing to query.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/ExecutionQueryImpl.java:315

    public ExecutionQueryImpl processInstanceId(String processInstanceId) {
        if (processInstanceId == null) {
            throw new FlowableIllegalArgumentException("Process instance id is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.processInstanceId = processInstanceId;
        } else {
            this.processInstanceId = processInstanceId;
        }
        return this;
    }

    @Override
    public ExecutionQuery processInstanceIds(Set<String> processInstanceIds) {
        if (processInstanceIds == null) {
            throw new FlowableIllegalArgumentException("Set of process instance ids is null");
        }
        if (processInstanceIds.isEmpty()) {
            throw new FlowableIllegalArgumentException("Set of process instance ids is empty");
        }

        if (inOrStatement) {
            this.currentOrQueryObject.processInstanceIds = processInstanceIds;
        } else {
            this.processInstanceIds = processInstanceIds;
        }
        return this;
    }

    @Override
    public ExecutionQueryImpl rootProcessInstanceId(String rootProcessInstanceId) {
        if (rootProcessInstanceId == null) {
            throw new FlowableIllegalArgumentException("Root process instance id is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.rootProcessInstanceId = rootProcessInstanceId;
        } else {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Guard with ids.isEmpty() before building the query and return an empty result early
  2. Fall back to a different query (e.g. by processDefinitionKey) when no ids are known
  3. Skip executing the query entirely in that code path
  4. Catch FlowableIllegalArgumentException and treat it as 'no results' if acceptable

Example fix

// before
Execution execution = runtimeService.createExecutionQuery().processInstanceIds(ids).singleResult();
// after
if (ids == null || ids.isEmpty()) {
    return Collections.emptyList();
}
List<Execution> executions = runtimeService.createExecutionQuery().processInstanceIds(ids).list();
Defensive patterns

Strategy: validation

Validate before calling

if (ids == null || ids.isEmpty()) {
    return Collections.emptyList();
}

Type guard

boolean isNonEmptyIdSet(Set<String> ids) {
    return ids != null && !ids.isEmpty();
}

Try / catch

try {
    return query.processInstanceIds(ids).list();
} catch (FlowableIllegalArgumentException e) {
    return Collections.emptyList();
}

Prevention

When it happens

Trigger: Calling processInstanceIds with a set that was created but never populated, or filtered down to zero elements before the query runs.

Common situations: Building ids from a prior search whose results were empty; filtering by tenant/permission removed all candidates; batch job with no work items for this run.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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