flowable/flowable-engine · error · ActivitiIllegalArgumentException

Set of process instance ids is null

Error message

Set of process instance ids is null

What it means

HistoricProcessInstanceQuery.processInstanceIds(Set<String>) requires a non-null set of process instance ids to filter history by. The library throws ActivitiIllegalArgumentException when the set is null, since an IN-clause filter needs an explicit collection. An empty set is rejected separately (see the 'is empty' error).

Solutions

  1. Ensure the set is populated before calling, e.g. new HashSet<>(Arrays.asList("id1","id2")).
  2. If the id list may be empty, skip applying the filter entirely instead of passing null.
  3. Null-check at the call site and throw a domain-specific error naming the missing data.
  4. Fix the upstream lookup that produced null instead of an empty collection.

Example fix

// before
Set<String> ids = null;
query.processInstanceIds(ids);
// after
Set<String> ids = collectProcessInstanceIds();
if (ids != null && !ids.isEmpty()) {
    query.processInstanceIds(ids);
}
Defensive patterns

Strategy: validation

Validate before calling

if (ids == null) throw new IllegalArgumentException("processInstanceIds required");
if (ids.isEmpty()) { /* skip filter or return empty result */ }

Type guard

boolean hasIds(java.util.Collection<?> c) { return c != null && !c.isEmpty(); }

Try / catch

try {
    query.processInstanceIds(ids);
} catch (ActivitiIllegalArgumentException e) {
    if (e.getMessage().contains("is null")) {
        throw new IllegalStateException("Caller bug: null id set", e);
    }
}

Prevention

When it happens

Trigger: Calling processInstanceIds(null), typically when the set is the result of an upstream lookup that returned nothing or a field that was never initialized.

Common situations: Collecting ids from a previous query whose result was null/absent; deserialized request payloads missing the ids field; service-to-service calls where the collection was lost in mapping.

Related errors


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

Appendix: source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/HistoricProcessInstanceQueryImpl.java:107

    public HistoricProcessInstanceQueryImpl(CommandExecutor commandExecutor) {
        super(commandExecutor);
    }

    @Override
    public HistoricProcessInstanceQueryImpl processInstanceId(String processInstanceId) {
        if (inOrStatement) {
            this.currentOrQueryObject.processInstanceId = processInstanceId;
        } else {
            this.processInstanceId = processInstanceId;
        }
        return this;
    }

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

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

    @Override
    public HistoricProcessInstanceQueryImpl processDefinitionId(String processDefinitionId) {
        if (inOrStatement) {
            this.currentOrQueryObject.processDefinitionId = processDefinitionId;
        } else {

View on GitHub (pinned to d6d39ce1c6)