flowable/flowable-engine · error · FlowableIllegalArgumentException

Variable name is required

Error message

Variable name is required

What it means

When completing a task via the task action endpoint, each variable supplied in the 'variables' array must have a 'name'. A RestVariable with a null name is rejected with FlowableIllegalArgumentException (HTTP 400) because the completion builder cannot register an unnamed variable.

Source

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

            throw new FlowableIllegalArgumentException("Task has no form defined");
        }
        
        FormInfo formInfo = taskService.getTaskFormModel(task.getId());
        if (formHandlerRestApiInterceptor != null) {
            return formHandlerRestApiInterceptor.convertTaskFormInfo(formInfo, task);
        } else {
            SimpleFormModel formModel = (SimpleFormModel) formInfo.getFormModel();
            return restResponseFactory.getFormModelString(new FormModelResponse(formInfo, formModel));
        }
    }

    protected void completeTask(Task task, TaskActionRequest actionRequest) {
        TaskCompletionBuilder taskCompletionBuilder = taskService.createTaskCompletionBuilder();

        if (actionRequest.getVariables() != null) {
            for (RestVariable var : actionRequest.getVariables()) {
                if (var.getName() == null) {
                    throw new FlowableIllegalArgumentException("Variable name is required");
                }

                Object actualVariableValue = restResponseFactory.getVariableValue(var);
                if (var.getVariableScope() != null && RestVariable.RestVariableScope.LOCAL.equals(var.getVariableScope())) {
                    taskCompletionBuilder.variableLocal(var.getName(), actualVariableValue);
                } else {
                    taskCompletionBuilder.variable(var.getName(), actualVariableValue);
                }

            }
        }

        if (actionRequest.getTransientVariables() != null) {
            for (RestVariable var : actionRequest.getTransientVariables()) {
                if (var.getName() == null) {
                    throw new FlowableIllegalArgumentException("Transient variable name is required");
                }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Ensure every object in the variables array includes a non-null name.
  2. Validate the request body client-side before sending.
  3. Fix client-side DTO mapping so the variable name is populated from your data source.
  4. Remove malformed variable entries rather than sending them with an empty name.

Example fix

// before
{"action":"complete","variables":[{"value":"x"}]}

// after
{"action":"complete","variables":[{"name":"myVar","value":"x"}]}
Defensive patterns

Strategy: validation

Validate before calling

vars.forEach(v => { if (!v.name) throw new Error('every completion variable needs a name'); });

Type guard

const validVars = vars.filter(v => typeof v.name === 'string' && v.name.length > 0);

Try / catch

try { await api.post(`/cmmn-runtime/tasks/${id}`, body); } catch (e) { if (e.response && e.response.status === 400) { /* fix payload: add variable names */ } throw e; }

Prevention

When it happens

Trigger: POST /cmmn-runtime/tasks/{taskId} with action 'complete' and a body where any element of the variables array lacks the name field (null, absent, or explicitly null in JSON).

Common situations: Hand-written JSON payloads missing 'name'; client serializers dropping null fields and sending {"value":...} only; programmatic request construction with unset name.

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/51a97ed219868d7c. Report an issue: GitHub.