flowable/flowable-engine · error · FlowableIllegalArgumentException

request body could not be transformed to a RestVariable inst

Error message

request body could not be transformed to a RestVariable instance.

What it means

Flowable REST throws FlowableIllegalArgumentException when the request body of a variable update cannot be deserialized by Jackson into a RestVariable instance. The body is not valid JSON for the variable schema (wrong Content-Type, malformed JSON, or unsupported structure).

Source

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

    public RestVariable updateVariable(@ApiParam(name = "processInstanceId") @PathVariable("processInstanceId") String processInstanceId, @ApiParam(name = "variableName") @PathVariable("variableName") String variableName,
            HttpServletRequest request) {

        Execution execution = getExecutionFromRequestWithoutAccessCheck(processInstanceId);

        RestVariable result = null;
        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("request body could not be transformed to a 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 single variable on a process instance asynchronously", tags = { "Process Instance Variables" }, nickname = "updateProcessInstanceVariableAsync",
            notes = "This endpoint can be used in 2 ways: By passing a JSON Body (RestVariable) or by passing a multipart/form-data Object.\n"
                    + "Note that scope is ignored, only local variables can be set in a process instance.\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.")

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Send a complete RestVariable JSON object: {"name":"...","type":"...","value":...} with Content-Type: application/json.
  2. Validate the JSON body with a linter/client before sending.
  3. Check that no proxy/gateway truncates or transforms the request body.

Example fix

// before
PUT .../variables/count  body: 42
// after
PUT .../variables/count  body: {"name":"count","type":"integer","value":42}
Defensive patterns

Strategy: validation

Validate before calling

JSON.parse(JSON.stringify({name: varName, type: varType, value: varValue})); // ensure serializable valid body

Type guard

const isRestVariable = (b) => b != null && typeof b === 'object' && typeof b.name === 'string' && 'value' in b;

Try / catch

try { put(url, body, {headers:{'Content-Type':'application/json'}}); } catch (e) { if (/RestVariable/.test(e.response?.data?.message || '')) { /* fix body shape */ } throw e; }

Prevention

When it happens

Trigger: PUT /runtime/process-instances/{id}/variables/{name} with a non-JSON body, syntactically invalid JSON, or a body sent without application/json content type so readValue fails.

Common situations: Client sends form-encoded/plain text instead of JSON; truncation of the body by a proxy; sending a bare value (e.g. just 42) instead of a RestVariable object with name/type/value.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


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