flowable/flowable-engine · error · FlowableIllegalArgumentException

Variable name is required

Error message

Variable name is required

What it means

Thrown by setSimpleVariable when the RestVariable deserialized from the JSON request body has no 'name' field. Every task variable created or updated via the REST API must carry a name. A nameless variable cannot be keyed in the engine's variable store.

Source

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

                stream.close();

            } else {
                throw new FlowableContentNotSupportedException("Serialized objects are not allowed");
            }

            return getVariableFromRequestWithoutAccessCheck(task, variableName, scope, false);

        } catch (IOException ioe) {
            throw new FlowableIllegalArgumentException("Error getting binary variable", ioe);
        } catch (ClassNotFoundException ioe) {
            throw new FlowableContentNotSupportedException("The provided body contains a serialized object for which the class was not found: " + ioe.getMessage());
        }

    }

    protected RestVariable setSimpleVariable(RestVariable restVariable, Task task, boolean isNew) {
        if (restVariable.getName() == null) {
            throw new FlowableIllegalArgumentException("Variable name is required");
        }

        // Figure out scope, revert to local is omitted
        RestVariableScope scope = restVariable.getVariableScope();
        if (scope == null) {
            scope = RestVariableScope.LOCAL;
        }

        Object actualVariableValue = restResponseFactory.getVariableValue(restVariable);
        setVariable(task, restVariable.getName(), actualVariableValue, scope, isNew);

        return getVariableFromRequestWithoutAccessCheck(task, restVariable.getName(), scope, false);
    }

    protected void setVariable(Task task, String name, Object value, RestVariableScope scope, boolean isNew) {
        // Create can only be done on new variables. Existing variables should
        // be updated using PUT
        boolean hasVariable = hasVariableOnScope(task, name, scope);

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Add the 'name' field to each variable object in the request body
  2. Check client serialization key naming (lower-case 'name')
  3. Validate the body payload before sending

Example fix

// before
{"type":"string","value":"hello"}
// after
{"name":"myVar","type":"string","value":"hello"}
Defensive patterns

Strategy: validation

Validate before calling

const vars = Array.isArray(body.variables) ? body.variables : [body];
vars.forEach((v, i) => { if (!v || typeof v.name !== 'string' || v.name.length === 0) throw new Error(`variable at index ${i} missing 'name'`); });

Type guard

const hasName = (v) => v != null && typeof v === 'object' && typeof v.name === 'string' && v.name.trim() !== '';

Try / catch

try { await createVariables(body) } catch (e) { if (/Variable name is required/.test(e.message)) console.error('payload variable missing name:', body); throw e; }

Prevention

When it happens

Trigger: POST/PUT to the task variables endpoints with a JSON body element like {"type":"string","value":"x"} missing the 'name' property.

Common situations: Hand-written JSON bodies omitting 'name'; clients mapping objects with different key casing (e.g. 'variableName'); programmatically built bodies where the name field was null.

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/3a58e1d41e2b0a8c. Report an issue: GitHub.