flowable/flowable-engine · error · FlowableIllegalArgumentException

Set of process instance ids is null

Error message

Set of process instance ids is null

What it means

Flowable's HistoricProcessInstanceQuery.processInstanceIds(Set<String>) requires a non-null set of process instance ids. The API throws FlowableIllegalArgumentException immediately at query-build time when the argument is null, rather than failing later at query execution. This fail-fast validation prevents building a query with an undefined id filter.

Source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/HistoricProcessInstanceQueryImpl.java:161

    public HistoricProcessInstanceQueryImpl(CommandExecutor commandExecutor, ProcessEngineConfigurationImpl processEngineConfiguration) {
        super(commandExecutor, processEngineConfiguration.getVariableServiceConfiguration());
        this.processEngineConfiguration = processEngineConfiguration;
    }

    @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 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 HistoricProcessInstanceQueryImpl processDefinitionId(String processDefinitionId) {
        if (inOrStatement) {
            this.currentOrQueryObject.processDefinitionId = processDefinitionId;
        } else {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Initialize the set before calling processInstanceIds, e.g. Set<String> ids = new HashSet<>(...);
  2. Skip the processInstanceIds call (or use a fallback filter) when the collection is null
  3. Guard with a null check or Objects.requireNonNullElse(ids, Collections.emptySet()) and only apply the filter when non-empty
  4. If the set may legitimately be empty, handle the empty case separately (empty sets also throw, see error 1921)

Example fix

// before
query.processInstanceIds(ids); // NPE-prone / throws when ids == null
// after
if (ids != null && !ids.isEmpty()) {
    query.processInstanceIds(ids);
}
Defensive patterns

Strategy: validation

Validate before calling

if (ids == null) {
    throw new IllegalArgumentException("processInstanceIds must be non-null before building the query");
}
query.processInstanceIds(ids);

Type guard

boolean isValidIdSet(Set<String> ids) {
    return ids != null;
}

Try / catch

try {
    query.processInstanceIds(ids);
} catch (FlowableIllegalArgumentException e) {
    if (e.getMessage().contains("null")) {
        ids = Collections.emptySet(); // handle missing ids explicitly
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling historicProcessInstanceQuery().processInstanceIds(ids) where ids is null — e.g. a caller passes an uninitialized variable, a method returns null instead of a set, or a null is forwarded from an upstream parameter.

Common situations: Building dynamic queries where the id set comes from an optional request parameter, a collection lookup that returned null, or refactoring that changed an empty-set default into null.

Related errors


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