flowable/flowable-engine · error · FlowableIllegalArgumentException

Value-only query (without a variable-name) is only…

Error message

Value-only query (without a variable-name) is only supported when using 'equals' operation.

What it means

Querying historic process instances by variable value without a variable name (a value-only search across all variables) is only meaningful with the EQUALS operation. addVariables throws FlowableIllegalArgumentException when the variable name is null but the operation is anything other than equals.

Solutions

  1. Use the equals operation for value-only queries: variable=|equals|someValue
  2. Provide a variable name if you need like/gt/lt or other operations
  3. Catch FlowableIllegalArgumentException (HTTP 400) and enforce the name+operation rule in the client

Example fix

// before
GET /history/historic-process-instances?variable=|like|%acme%

// after
GET /history/historic-process-instances?variable=customerName|like|%acme%
Defensive patterns

Strategy: validation

Validate before calling

if (variables.some(v => (v.name == null || v.name === '') && v.operation !== 'equals')) {
  throw new Error('Value-only queries require the equals operation');
}

Type guard

function isLegalValueOnlyQuery(v) { return v.name != null || v.operation === 'equals'; }

Try / catch

try { return await queryHistoricInstances(vars); } catch (e) { if (e.status === 400 && /Value-only query/.test(e.message)) switchToEqualsOrAddName(vars); else throw e; }

Prevention

When it happens

Trigger: GET /history/historic-process-instances with a nameless variable filter combined with a non-equals operation, e.g. variable=|like|%foo% or |gt|10.

Common situations: Client UI allows selecting an operator without entering a variable name; generic query builders that omit the name when unknown; experimenting with value-only search using the wrong operator.

Understand the failure class

Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.

Related errors


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

Appendix: source

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

    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 {
                    processInstanceQuery.variableValueEquals(variable.getName(), actualValue);
                }
                break;

            case EQUALS_IGNORE_CASE:
                if (actualValue instanceof String) {
                    processInstanceQuery.variableValueEqualsIgnoreCase(variable.getName(), (String) actualValue);
                } else {
                    throw new FlowableIllegalArgumentException("Only string variable values are supported when ignoring casing, but was: " + actualValue.getClass().getName());
                }

View on GitHub (pinned to d6d39ce1c6)