flowable/flowable-engine · error · FlowableException

Invalid body was supplied

Error message

Invalid body was supplied

What it means

Thrown when updateVariable successfully reads the request stream but the parsed RestVariable is null — i.e. an empty or null body was supplied. Unlike the parse failure case, the body deserialized fine (or was empty), so Flowable raises a plain FlowableException ('Invalid body was supplied') to reject the request before any variable write occurs.

Source

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

        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));
        }
        return result;
    }
    
    @ApiOperation(value = "Update a variable on a plan item asynchronously", tags = { "Plan Item Instances" }, nickname = "updatePlanItemVariableAsync",
            notes = "This endpoint can be used in 2 ways: By passing a JSON Body (RestVariable) or by passing a multipart/form-data Object.\n"
                    + "NB: Swagger V2 specification does not support this use case that is why this endpoint might be buggy/incomplete if used with other tools.")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "body", type = "org.flowable.rest.service.api.engine.variable.RestVariable", value = "Update a variable on a plan item instance", paramType = "body", example =
                    "{\n" +
                            "    \"name\":\"intProcVar\"\n" +
                            "    \"type\":\"integer\"\n" +

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Always send a valid RestVariable JSON body, e.g. {"name":"amount","type":"integer","value":42}.
  2. Check the HTTP client is not silently dropping the body on PUT (some clients require explicit body/Content-Length).
  3. Log/inspect the outgoing request payload to confirm it is non-empty before sending.

Example fix

// before
client.put(url, null);
// after
client.putJson(url, "{\"name\":\"amount\",\"value\":42}");
Defensive patterns

Strategy: validation

Validate before calling

if (!body || Object.keys(body).length === 0) { throw new Error('PUT body required for variable update'); }

Type guard

function hasBody(b) { return b != null && typeof b === 'object' && Object.keys(b).length > 0; }

Try / catch

try { api.updateVariable(id, name, body); }
catch (FlowableException e) { if ('Invalid body was supplied'.equals(e.getMessage())) { rebuildBodyAndRetryOnce(); } else throw e; }

Prevention

When it happens

Trigger: PUT /cmmn-runtime/plan-item-instances/{id}/variables/{name} with an empty request body, or a body that deserializes to a null RestVariable.

Common situations: Clients sending PUT with no payload; Content-Length 0 behind a gateway; a templating bug that renders an empty JSON document; curl invocations missing -d/--data.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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