flowable/flowable-engine · error · FlowableIllegalArgumentException

Variable value is missing for variable:

Error message

Variable value is missing for variable: 

What it means

Thrown as FlowableIllegalArgumentException when a variable predicate in the historic variable instance query has a null value. Value is required because the operation (equals, like, greaterThan, ...) needs an operand to compare against; restResponseFactory.getVariableValue(variable) would otherwise have nothing to convert. The request is rejected with HTTP 400 before any query runs.

Source

Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/history/variable/HistoricVariableInstanceBaseResource.java:122

        HistoricVariableInstance varObject = historyService.createHistoricVariableInstanceQuery().id(varInstanceId).singleResult();

        if (varObject == null) {
            throw new FlowableObjectNotFoundException("Historic variable instance '" + varInstanceId + "' couldn't be found.", VariableInstanceEntity.class);
        } else {
            if (restApiInterceptor != null) {
                restApiInterceptor.accessHistoryVariableInfoById(varObject);
            }
            return restResponseFactory.createRestVariable(varObject.getVariableName(), varObject.getValue(), null, varInstanceId, CmmnRestResponseFactory.VARIABLE_HISTORY_VARINSTANCE, includeBinary);
        }
    }

    protected void addVariables(HistoricVariableInstanceQuery variableInstanceQuery, List<QueryVariable> variables) {
        for (QueryVariable variable : variables) {
            if (variable.getVariableOperation() == null) {
                throw new FlowableIllegalArgumentException("Variable operation is missing for variable: " + variable.getName());
            }
            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) {
                throw new FlowableIllegalArgumentException("Value-only query (without a variable-name) is not supported");
            }

            switch (variable.getVariableOperation()) {

            case EQUALS:
                variableInstanceQuery.variableValueEquals(variable.getName(), actualValue);
                break;

            default:

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Provide a concrete value for the predicate: {"name":"priority","operation":"equals","value":5}.
  2. To find unset variables, query the list endpoint without that variable filter and check variableValue == null in results (or query by name only), instead of a null-value predicate.
  3. Drop empty/blank filters client-side before building the query so no variable entry with null value is sent.
  4. Ensure the value's JSON type matches the stored variable type so getVariableValue can deserialize it.

Example fix

// before: 400 - value missing
{"variables":[{"name":"priority","operation":"equals"}]}

// after
{"variables":[{"name":"priority","operation":"equals","value":5}]}
Defensive patterns

Strategy: validation

Validate before calling

if (variables.stream().anyMatch(v -> v.getValue() == null)) {
    throw new IllegalArgumentException("variable filters cannot have null value; drop the filter instead");
}

Try / catch

try {
    HistoricVariableInstanceListResponse r = query(variables);
} catch (FlowableIllegalArgumentException e) {
    // HTTP 400: null value in variable predicate
}

Prevention

When it happens

Trigger: Query filter entry {"name":"priority","operation":"equals"} with no "value" key, or value explicitly null, on GET /cmmn-history/historic-variable-instances with a variables filter.

Common situations: Clients trying to express 'is null' queries — Flowable historic variable query predicates do not support null operands, so the value must be a concrete typed value; also occurs when optional UI fields are left empty and serialized as null instead of being dropped from the filter.

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/88a7c50fc497dceb. Report an issue: GitHub.