flowable/flowable-engine · error · FlowableIllegalArgumentException

Unsupported variable query operation:

Error message

Unsupported variable query operation: 

What it means

The variable query operation sent in the request is not one of the operations the CMMN REST task query supports (EQUALS, NOT_EQUALS, EQUALS_IGNORE_CASE, NOT_EQUALS_IGNORE_CASE, LIKE, LIKE_IGNORE_CASE, GREATER_THAN, GREATER_THAN_OR_EQUALS, LESS_THAN, LESS_THAN_OR_EQUALS, EXISTS, NOT_EXISTS). addProcessvariables' default branch throws FlowableIllegalArgumentException naming the operation.

Solutions

  1. Use one of the supported operation names exactly: EQUALS, NOT_EQUALS, EQUALS_IGNORE_CASE, NOT_EQUALS_IGNORE_CASE, LIKE, LIKE_IGNORE_CASE, GREATER_THAN, GREATER_THAN_OR_EQUALS, LESS_THAN, LESS_THAN_OR_EQUALS, EXISTS, NOT_EXISTS
  2. Fix the spelling/casing of variableOperation in the request body
  3. Compare against the org.flowable.cmmn.rest.service.api.runtime.task.QueryVariable.QueryVariableOperation enum for valid values
  4. Log the request body next to the exception message which echoes the invalid operation

Example fix

// before
{"processVariables":[{"name":"status","value":"open","variableOperation":"EQUALS_ICASE"}]}
// after
{"processVariables":[{"name":"status","value":"open","variableOperation":"EQUALS_IGNORE_CASE"}]}
Defensive patterns

Strategy: validation

Validate before calling

const OPS = ['EQUALS','NOT_EQUALS','EQUALS_IGNORE_CASE','NOT_EQUALS_IGNORE_CASE','LIKE','LIKE_IGNORE_CASE','GREATER_THAN','GREATER_THAN_OR_EQUALS','LESS_THAN','LESS_THAN_OR_EQUALS','EXISTS','NOT_EXISTS'];
for (const v of req.processVariables) if (!OPS.includes(v.variableOperation)) throw new Error('Unsupported variableOperation: ' + v.variableOperation);

Try / catch

try { await queryTasks(req); } catch (e) { if (e.message.startsWith('Unsupported variable query operation')) { const bad = e.message.split(': ')[1]; /* fix or drop that filter */ } throw e; }

Prevention

When it happens

Trigger: POST /cmmn-query/tasks with a processVariables entry whose variableOperation is misspelled, unknown (e.g. "notEqualsIgnoreCase" wrong casing on an unparseable enum) or otherwise not in the QueryVariable.QueryVariableOperation enum.

Common situations: Typos in variableOperation; clients copied from process-engine REST API versions with different operation names; frameworks sending uppercase/lowercase variants the enum cannot resolve.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/task/TaskBaseResource.java:548

            case LIKE_IGNORE_CASE:
                if (actualValue instanceof String) {
                    taskQuery.processVariableValueLikeIgnoreCase(variable.getName(), (String) actualValue);
                } else {
                    throw new FlowableIllegalArgumentException("Only string variable values are supported using like, but was: " + actualValue.getClass().getName());
                }
                break;

            case EXISTS:
                taskQuery.processVariableExists(variable.getName());
                break;

            case NOT_EXISTS:
                taskQuery.processVariableNotExists(variable.getName());
                break;

            default:
                throw new FlowableIllegalArgumentException("Unsupported variable query operation: " + variable.getVariableOperation());
            }
        }
    }

    /**
     * Returns the {@link Task} that is requested and calls the access interceptor.
     * Throws the right exceptions when bad request was made or instance was not found.
     */
    protected Task getTaskFromRequest(String taskId) {
        Task task = getTaskFromRequestWithoutAccessCheck(taskId);
        if (restApiInterceptor != null) {
            restApiInterceptor.accessTaskInfoById(task);
        }

        return task;
    }

    protected Task getTaskFromRequestWithoutAccessCheck(String taskId) {

View on GitHub (pinned to d6d39ce1c6)