flowable/flowable-engine · error · FlowableIllegalArgumentException

Request didn't contain a list of variables to create.

Error message

Request didn't contain a list of variables to create.

What it means

FlowableIllegalArgumentException thrown by createTaskVariable when the request body parsed successfully but contained an empty or missing variables list. Creating task variables requires at least one variable in the array. Both a null list and a zero-length list trigger this.

Solutions

  1. Ensure at least one variable object is present in the 'variables' array before calling the endpoint
  2. Guard client-side: skip the API call when the variable collection is empty
  3. Fall back to the single-variable endpoint for one variable
  4. Log/validate the payload before sending

Example fix

// before
{"variables": []}
// after
{"variables": [{"name":"k","type":"string","value":"v"}]}
Defensive patterns

Strategy: validation

Validate before calling

if (!Array.isArray(vars) || vars.length === 0) throw new Error('refusing to call createTaskVariable with an empty variables list');

Type guard

const hasVariables = (vars) => Array.isArray(vars) && vars.length > 0;

Try / catch

try { await createVariables(payload) } catch (e) { if (/didn't contain a list of variables/.test(e.message)) console.warn('skipping empty variable batch'); throw e; }

Prevention

When it happens

Trigger: POST /cmmn-runtime/tasks/{taskId}/variables with body {"variables":[]} or omitting the variables field entirely.

Common situations: Client code building the list from an empty collection/map; filters that removed all variables before sending; template-generated requests with unfilled variables.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

            List<RestVariable> inputVariables = new ArrayList<>();
            List<RestVariable> resultVariables = new ArrayList<>();
            result = resultVariables;

            try {
                @SuppressWarnings("unchecked")
                List<Object> variableObjects = (List<Object>) objectMapper.readValue(request.getInputStream(), List.class);
                for (Object restObject : variableObjects) {
                    RestVariable restVariable = objectMapper.convertValue(restObject, RestVariable.class);
                    inputVariables.add(restVariable);
                }
                
            } catch (Exception e) {
                throw new FlowableIllegalArgumentException("Failed to serialize to a RestVariable instance", e);
            }

            if (inputVariables == null || inputVariables.size() == 0) {
                throw new FlowableIllegalArgumentException("Request didn't contain a list of variables to create.");
            }

            RestVariableScope sharedScope = null;
            RestVariableScope varScope = null;
            Map<String, Object> variablesToSet = new HashMap<>();

            for (RestVariable var : inputVariables) {
                // Validate if scopes match
                varScope = var.getVariableScope();
                if (var.getName() == null) {
                    throw new FlowableIllegalArgumentException("Variable name is required");
                }

                if (varScope == null) {
                    varScope = RestVariableScope.LOCAL;
                }
                if (sharedScope == null) {
                    sharedScope = varScope;

View on GitHub (pinned to d6d39ce1c6)