flowable/flowable-engine · error · FlowableIllegalArgumentException

Variable name in the body should be equal to the name used i

Error message

Variable name in the body should be equal to the name used in the requested URL.

What it means

Thrown by PlanItemInstanceVariableResource.updateVariable when the request is a multipart upload and the variable name stored in the submitted body/entry does not match the {variableName} path segment. Flowable requires the URL and body to agree to avoid ambiguous writes. The check is FlowableIllegalArgumentException, mapped to 409/400 by the REST exception mapper.

Source

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

    })
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "Indicates both the plan item instance and variable were found and variable is updated."),
            @ApiResponse(code = 404, message = "Indicates the requested plan item instance was not found or the plan item instance does not have a variable with the given name. Status description contains additional information about the error.")
    })
    @PutMapping(value = "/cmmn-runtime/plan-item-instances/{planItemInstanceId}/variables/{variableName}", produces = "application/json", consumes = {
            "application/json", "multipart/form-data" })
    public RestVariable updateVariable(@ApiParam(name = "planItemInstanceId") @PathVariable("planItemInstanceId") String planItemInstanceId,
            @ApiParam(name = "variableName") @PathVariable("variableName") String variableName, HttpServletRequest request) {

        PlanItemInstance planItem = getPlanItemInstanceFromRequest(planItemInstanceId);

        RestVariable result = null;
        if (request instanceof MultipartHttpServletRequest) {
            result = setBinaryVariable((MultipartHttpServletRequest) request, planItem.getId(), CmmnRestResponseFactory.VARIABLE_PLAN_ITEM, false,
                    false, RestVariable.RestVariableScope.LOCAL, createVariableInterceptor(planItem));

            if (!result.getName().equals(variableName)) {
                throw new FlowableIllegalArgumentException("Variable name in the body should be equal to the name used in the requested URL.");
            }

        } else {
            RestVariable restVariable = null;
            try {
                restVariable = objectMapper.readValue(request.getInputStream(), RestVariable.class);
            } catch (Exception e) {
                throw new FlowableIllegalArgumentException("Error converting request body to RestVariable instance", e);
            }

            if (restVariable == null) {
                throw new FlowableException("Invalid body was supplied");
            }
            if (!restVariable.getName().equals(variableName)) {
                throw new FlowableIllegalArgumentException("Variable name in the body should be equal to the name used in the requested URL.");
            }

            result = setSimpleVariable(restVariable, planItem.getId(), false, false, RestVariable.RestVariableScope.LOCAL, CmmnRestResponseFactory.VARIABLE_PLAN_ITEM, createVariableInterceptor(planItem));

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Make the multipart form field name exactly match the {variableName} path segment.
  2. Derive the URL from the same variable object used to build the body instead of hardcoding both.
  3. Send the variable as JSON (application/json) instead of multipart if a binary file is not involved, so the body's name field controls the value.

Example fix

// before
form.field("value", data); client.put(".../variables/amount", form);
// after
form.field("amount", data); client.put(".../variables/amount", form);
Defensive patterns

Strategy: validation

Validate before calling

if (formFieldName !== pathVariableName) { throw new Error(`multipart field '${formFieldName}' != URL variable '${pathVariableName}'`); }

Try / catch

try { api.updateVariable(id, name, body); }
catch (FlowableIllegalArgumentException e) { if (String(e.getMessage()).includes('equal to the name used in the requested URL')) fixFieldName(); else throw e; }

Prevention

When it happens

Trigger: PUT /cmmn-runtime/plan-item-instances/{id}/variables/{variableName} with a multipart form field whose name differs from the path variable (e.g. path says 'amount', form field is 'value').

Common situations: Hand-built multipart clients where the form field name is hardcoded separately from the URL; templated API wrappers substituting one name in the URL and another in the body; copy-pasted request code after renaming a variable.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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