flowable/flowable-engine · error · FlowableIllegalArgumentException

Process definition id is null

Error message

Process definition id is null

What it means

ProcessInstanceQueryImpl.processDefinitionId(String) throws FlowableIllegalArgumentException('Process definition id is null') when the given definition id is null. The id is the primary exact-match filter for process instances, and a null cannot produce a valid equality condition, so the check rejects it during query construction before storing it on the query or its OR-query object.

Solutions

  1. Null-check the id before calling processDefinitionId and skip the query/filter when absent
  2. Verify the upstream lookup actually found the definition — handle empty singleResult() before reading getId()
  3. Use processDefinitionKey or processDefinitionName if the exact id is not known
  4. Catch FlowableIllegalArgumentException around query building and surface a clear validation message

Example fix

// before
ProcessDefinition def = repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).singleResult();
query.processDefinitionId(def.getId()); // NPE risk / def may be null

// after
ProcessDefinition def = repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).singleResult();
if (def != null) {
    query.processDefinitionId(def.getId());
}
Defensive patterns

Strategy: validation

Validate before calling

if (processDefinitionId != null) {
    query.processDefinitionId(processDefinitionId);
}

Type guard

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

Try / catch

try {
    query.processDefinitionId(defId);
} catch (FlowableIllegalArgumentException e) {
    throw new BadRequestException("processDefinitionId must not be null", e);
}

Prevention

When it happens

Trigger: Calling .processDefinitionId(null), typically when the id comes from a variable populated by a prior lookup that returned null (e.g. singleResult() on an empty result), a missing path variable, or an unbound DTO field.

Common situations: Chained queries where ProcessDefinitionQuery.singleResult() returns null for a nonexistent key and its getId() result is passed on; REST handlers with optional path parameters; migrated code where an id field changed name and silently stopped being populated.

Related errors


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

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/ProcessInstanceQueryImpl.java:406

    @Override
    public ProcessInstanceQuery processDefinitionVersion(Integer processDefinitionVersion) {
        if (processDefinitionVersion == null) {
            throw new FlowableIllegalArgumentException("Process definition version is null");
        }

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

    @Override
    public ProcessInstanceQueryImpl processDefinitionId(String processDefinitionId) {
        if (processDefinitionId == null) {
            throw new FlowableIllegalArgumentException("Process definition id is null");
        }

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

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

View on GitHub (pinned to d6d39ce1c6)