flowable/flowable-engine · error · FlowableException

Invalid body was supplied

Error message

Invalid body was supplied

What it means

This FlowableException is thrown by updateVariable on the execution variable REST resource when the request body could not be parsed into a RestVariable (the deserialization produced null). The endpoint requires a JSON body representing the variable to set; an absent, empty, or unparseable body leaves restVariable null and the update is rejected. It signals a malformed request rather than a server-side problem.

Source

Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/process/ExecutionVariableResource.java:121

        if (request instanceof MultipartHttpServletRequest) {
            result = setBinaryVariable((MultipartHttpServletRequest) request, execution, false, false);

            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, execution, false, false);
        }
        return result;
    }
    
    @ApiOperation(value = "Update a variable on an execution asynchronously", tags = { "Executions" }, nickname = "updateExecutionVariableAsync",
            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 an execution", paramType = "body", example = "{\n" +
                    "    \"name\":\"intProcVar\"\n" +
                    "    \"type\":\"integer\"\n" +
                    "    \"value\":123,\n" +

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Send a valid JSON RestVariable body, e.g. {"name":"myVar","type":"string","value":"foo"}
  2. Set the Content-Type header to application/json
  3. Verify the request actually contains a body (curl -d @file.json) rather than an empty string
  4. Confirm the JSON top-level is an object, not the literal null
  5. If the body is intentionally malformed, expect FlowableIllegalArgumentException 400 instead and fix the payload

Example fix

// before
curl -X PUT -H 'Content-Type: application/json' \
  '.../runtime/process-instances/5/variables/myVar' -d ''
// after
curl -X PUT -H 'Content-Type: application/json' \
  '.../runtime/process-instances/5/variables/myVar' \
  -d '{"name":"myVar","type":"string","value":"foo"}'
Defensive patterns

Strategy: validation

Validate before calling

const body = { name: variableName, type, value };
const json = JSON.stringify(body);
if (!json || json === '"null"') throw new Error('RestVariable body required');
await fetch(url, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: json });

Type guard

function isValidRestVariable(b) {
  return !!b && typeof b === 'object' && !Array.isArray(b) && typeof b.name === 'string' && b.name.length > 0;
}

Try / catch

try { await updateVariable(...); } catch (e) { if (e.status === 400 && /Invalid body/.test(e.body?.message || '')) { /* fix payload and retry once */ } else { throw e; } }

Prevention

When it happens

Trigger: PUT/POST to /runtime/process-instances/{executionId}/variables/{variableName} with an empty body, a body that is not valid JSON, or a body that Jackson deserializes to null (e.g. literal 'null').

Common situations: Clients forgetting to send a request body, wrong Content-Type (e.g. text/plain instead of application/json so Jackson never parses it), shell/curl quoting mistakes producing an empty -d argument, or proxies stripping the body.

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/8add9f6a1375bf69. Report an issue: GitHub.