flowable/flowable-engine · error · FlowableIllegalArgumentException

Variable value is missing for variable: " +…

Error message

Variable value is missing for variable: " + variable.getName()

What it means

For EXISTS/NOT_EXISTS operations the value is optional, but every other variable query operation requires a value to compare against. addVariables throws FlowableIllegalArgumentException when variable.getValue() is null for those operations, since the resulting query predicate would be meaningless.

Solutions

  1. Provide the value in the variable filter for all operations except exists/notExists
  2. Use exists/notExists if you only want to test variable presence without a value
  3. Catch FlowableIllegalArgumentException (HTTP 400) and validate filter completeness before sending

Example fix

// before
GET /history/historic-process-instances?variable=status|equals|

// after
GET /history/historic-process-instances?variable=status|equals|ACTIVE
// or presence check:
GET /history/historic-process-instances?variable=status|exists|
Defensive patterns

Strategy: validation

Validate before calling

for (const v of variables) {
  const presenceOnly = v.operation === 'exists' || v.operation === 'notExists';
  if (!presenceOnly && (v.value === undefined || v.value === null)) {
    throw new Error(`Variable ${v.name}: value required for ${v.operation}`);
  }
}

Type guard

function needsValue(v) { return v.operation !== 'exists' && v.operation !== 'notExists'; }

Try / catch

try { return await queryHistoricInstances(vars); } catch (e) { if (e.status === 400 && /Variable value is missing/.test(e.message)) fixFilters(vars); else throw e; }

Prevention

When it happens

Trigger: GET /history/historic-process-instances?variable=name|equals| (empty value) or a variable filter with an operation like gt/like/equals but no value supplied.

Common situations: Client omits the value when the variable is empty; null values lost during URL-encoding; frameworks dropping empty query segments.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/history/HistoricProcessInstanceBaseResource.java:317

    }

    protected HistoricProcessInstance getHistoricProcessInstanceFromRequestWithoutAccessCheck(String processInstanceId) {
        HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        if (processInstance == null) {
            throw new FlowableObjectNotFoundException("Could not find a process instance with id '" + processInstanceId + "'.", HistoricProcessInstance.class);
        }

        return processInstance;
    }

    protected void addVariables(HistoricProcessInstanceQuery processInstanceQuery, List<QueryVariable> variables) {
        for (QueryVariable variable : variables) {
            if (variable.getVariableOperation() == null) {
                throw new FlowableIllegalArgumentException("Variable operation is missing for variable: " + variable.getName());
            }
            if (variable.getVariableOperation() != QueryVariableOperation.EXISTS && variable.getVariableOperation() != QueryVariableOperation.NOT_EXISTS) {
                if (variable.getValue() == null) {
                    throw new FlowableIllegalArgumentException("Variable value is missing for variable: " + variable.getName());
                }
            }

            boolean nameLess = variable.getName() == null;

            Object actualValue = restResponseFactory.getVariableValue(variable);

            // A value-only query is only possible using equals-operator
            if (nameLess && variable.getVariableOperation() != QueryVariableOperation.EQUALS) {
                throw new FlowableIllegalArgumentException("Value-only query (without a variable-name) is only supported when using 'equals' operation.");
            }

            switch (variable.getVariableOperation()) {

            case EQUALS:
                if (nameLess) {
                    processInstanceQuery.variableValueEquals(actualValue);
                } else {

View on GitHub (pinned to d6d39ce1c6)