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
- Ensure every object in the variables array includes a non-null name.
- Validate the request body client-side before sending.
- Fix client-side DTO mapping so the variable name is populated from your data source.
- 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
- Validate variable payloads client-side before sending
- Ensure serializers keep the name field
- Use typed DTOs that require name
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
- Variable operation is missing for variable: ${name}
- No variable name was found in request body.
- caseInstanceId is null
- caseInstanceId is null
- variables is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/51a97ed219868d7c.
Report an issue: GitHub.