flowable/flowable-engine · error · FlowableIllegalArgumentException

Variable name is required.

Error message

Variable name is required.

What it means

Each entry in startFormVariables must carry a name. createCaseInstance iterates request.getStartFormVariables() and throws FlowableIllegalArgumentException (HTTP 400) if any RestVariable has a null name, since an unnamed variable cannot be bound to the case start form.

Solutions

  1. Add the missing "name" property to every object in startFormVariables
  2. Filter out entries with null/blank names on the client before sending
  3. Fix form serialization so field names are always included
  4. Validate the request payload before posting

Example fix

// before
{"caseDefinitionKey":"myCase","startFormVariables":[{"value":42}]}
// after
{"caseDefinitionKey":"myCase","startFormVariables":[{"name":"amount","value":42}]}
Defensive patterns

Strategy: validation

Validate before calling

if (request.getStartFormVariables() != null) {
    request.getStartFormVariables().stream()
        .filter(v -> v.getName() == null || v.getName().isEmpty())
        .findAny()
        .ifPresent(v -> { throw new IllegalArgumentException("All startFormVariables need a name"); });
}

Type guard

boolean hasName(RestVariable v) { return v != null && v.getName() != null && !v.getName().trim().isEmpty(); }

Try / catch

try {
    startCase(request);
} catch (HttpClientErrorException.BadRequest e) {
    if (e.getResponseBodyAsString().contains("Variable name is required")) {
        log.error("A variable entry without name was sent");
    }
}

Prevention

When it happens

Trigger: POST /cmmn-runtime/case-instances where any object in the startFormVariables array lacks a "name" property (name null/absent).

Common situations: Hand-written JSON entries with only "value" set, form serialization code that drops empty field names, list construction that appends placeholder RestVariable objects.

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/58740060616621ca. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/caze/CaseInstanceCollectionResource.java:355

        if (paramsSet > 1) {
            throw new FlowableIllegalArgumentException("Only one of caseDefinitionId or caseDefinitionKey should be set.");
        }

        if (request.isTenantSet()) {
            // Tenant-id can only be used with either key or message
            if (request.getCaseDefinitionId() != null) {
                throw new FlowableIllegalArgumentException("TenantId can only be used with either caseDefinitionKey.");
            }
        }

        Map<String, Object> startVariables = null;
        Map<String, Object> transientVariables = null;
        Map<String, Object> startFormVariables = null;
        if (request.getStartFormVariables() != null) {
            startFormVariables = new HashMap<>();
            for (RestVariable variable : request.getStartFormVariables()) {
                if (variable.getName() == null) {
                    throw new FlowableIllegalArgumentException("Variable name is required.");
                }
                startFormVariables.put(variable.getName(), restResponseFactory.getVariableValue(variable));
            }

        }

        if (request.getVariables() != null) {
            startVariables = new HashMap<>();
            for (RestVariable variable : request.getVariables()) {
                if (variable.getName() == null) {
                    throw new FlowableIllegalArgumentException("Variable name is required.");
                }
                startVariables.put(variable.getName(), restResponseFactory.getVariableValue(variable));
            }
        }

        if (request.getTransientVariables() != null) {
            transientVariables = new HashMap<>();

View on GitHub (pinned to d6d39ce1c6)