flowable/flowable-engine · error · org.flowable.common.engine.api.FlowableIllegalArgumentException

processInstanceId is null

Error message

processInstanceId is null

What it means

HistoricVariableInstanceQueryImpl.processInstanceId requires a non-null process instance id and throws FlowableIllegalArgumentException when null is passed. The query builder fails fast so an invalid query never reaches the database. Supplying null would otherwise produce ambiguous or full-table results.

Solutions

  1. Only call processInstanceId when the id is non-null; omit the clause otherwise
  2. Resolve the id correctly before building the query (check the execution/context)
  3. Validate the id with Objects.requireNonNull or an if-check before the call
  4. If querying across instances, drop the processInstanceId constraint instead of passing null

Example fix

// before
query.processInstanceId(execution.getProcessInstanceId());
// after
String pid = execution.getProcessInstanceId();
if (pid != null) { query.processInstanceId(pid); }
Defensive patterns

Strategy: validation

Validate before calling

if (processInstanceId == null || processInstanceId.isBlank()) {
    return; // skip clause instead of calling the API
}
query.processInstanceId(processInstanceId);

Type guard

static boolean hasProcessInstanceId(String pid) {
    return pid != null && !pid.isBlank();
}

Try / catch

try {
    query.processInstanceId(pid);
} catch (org.flowable.common.engine.api.FlowableIllegalArgumentException e) {
    // log and query without the clause, or rethrow with context
}

Prevention

When it happens

Trigger: Calling createHistoricVariableInstanceQuery().processInstanceId(null), often when the id comes from a nullable variable, an optional execution, or a failed processInstance lookup.

Common situations: Passing the result of an API that returned null (e.g. DelegateExecution.getProcessInstanceId() in odd contexts); chaining queries built from optional request parameters; unit tests with uninitialized ids.

Related errors


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

Appendix: source

Thrown at modules/flowable-variable-service/src/main/java/org/flowable/variable/service/impl/HistoricVariableInstanceQueryImpl.java:83

        super(commandContext);
        this.variableServiceConfiguration = variableServiceConfiguration;
    }

    public HistoricVariableInstanceQueryImpl(CommandExecutor commandExecutor, VariableServiceConfiguration variableServiceConfiguration) {
        super(commandExecutor);
        this.variableServiceConfiguration = variableServiceConfiguration;
    }

    @Override
    public HistoricVariableInstanceQuery id(String id) {
        this.id = id;
        return this;
    }

    @Override
    public HistoricVariableInstanceQueryImpl processInstanceId(String processInstanceId) {
        if (processInstanceId == null) {
            throw new FlowableIllegalArgumentException("processInstanceId is null");
        }
        this.processInstanceId = processInstanceId;
        return this;
    }

    @Override
    public HistoricVariableInstanceQuery processInstanceIds(Collection<String> processInstanceIds) {
        if (processInstanceIds == null || processInstanceIds.isEmpty()) {
            throw new FlowableIllegalArgumentException("processInstanceIds is empty");
        }
        this.processInstanceIds = processInstanceIds;
        return this;
    }

    @Override
    public HistoricVariableInstanceQueryImpl executionId(String executionId) {
        if (executionId == null) {
            throw new FlowableIllegalArgumentException("Execution id is null");

View on GitHub (pinned to d6d39ce1c6)