flowable/flowable-engine · error · ActivitiIllegalArgumentException

Set of process definition keys is null

Error message

Set of process definition keys is null

What it means

ProcessInstanceQueryImpl.processDefinitionKeys(Set<String>) throws ActivitiIllegalArgumentException with message 'Set of process definition keys is null' when the argument set is null (an empty set has its own distinct error). The IN-style key filter requires a concrete non-null set of keys; eager validation keeps malformed queries from reaching the database.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/ProcessInstanceQueryImpl.java:279

    @Override
    public ProcessInstanceQueryImpl processDefinitionKey(String processDefinitionKey) {
        if (processDefinitionKey == null) {
            throw new ActivitiIllegalArgumentException("Process definition key is null");
        }

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

    @Override
    public ProcessInstanceQuery processDefinitionKeys(Set<String> processDefinitionKeys) {
        if (processDefinitionKeys == null) {
            throw new ActivitiIllegalArgumentException("Set of process definition keys is null");
        }
        if (processDefinitionKeys.isEmpty()) {
            throw new ActivitiIllegalArgumentException("Set of process definition keys is empty");
        }

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

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

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Initialize collections eagerly (Collections.emptySet()) and treat empty as 'no filter' by skipping the call.
  2. Null-check lookup results before passing them into the query.
  3. Normalize deserialized DTOs: null list -> empty -> omit filter.
  4. Catch ActivitiIllegalArgumentException around query construction for a clear validation message.

Example fix

// before
query.processDefinitionKeys(config.getProcessKeys()); // may be null
// after
Set<String> keys = config.getProcessKeys();
if (keys != null && !keys.isEmpty()) {
    query = query.processDefinitionKeys(keys);
}
Defensive patterns

Strategy: validation

Validate before calling

if (keys == null || keys.isEmpty()) {
    // skip filter or short-circuit
}
else {
    query = query.processDefinitionKeys(keys);
}

Type guard

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

Try / catch

try {
    result = query.processDefinitionKeys(keys).list();
} catch (ActivitiIllegalArgumentException e) {
    if (e.getMessage().contains("process definition keys is null")) {
        throw new BadRequestException("processDefinitionKeys set must not be null");
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling .processDefinitionKeys(null) — typically a Set field never initialized, a null return from a configuration/authorization lookup, or a DTO with a missing keys list.

Common situations: Tenant/permission loaders returning null when no mappings exist; JSON request bodies omitting the keys array; static filter defaults that were never assigned.

Related errors


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