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
Thrown by updateVariable when the request body cannot be deserialized into a RestVariable object by Jackson (objectMapper.readValue). Flowable wraps the underlying parse exception in a FlowableIllegalArgumentException, indicating the client sent a malformed or non-JSON body.
Source
Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/caze/CaseInstanceVariableResource.java:108
HttpServletRequest request) {
CaseInstance caseInstance = getCaseInstanceFromRequestWithoutAccessCheck(caseInstanceId);
RestVariable result = null;
if (request instanceof MultipartHttpServletRequest) {
result = setBinaryVariable((MultipartHttpServletRequest) request, caseInstance.getId(), CmmnRestResponseFactory.VARIABLE_CASE, false,
false, RestVariable.RestVariableScope.GLOBAL, createVariableInterceptor(caseInstance));
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, caseInstance.getId(), false, false, RestVariable.RestVariableScope.GLOBAL, CmmnRestResponseFactory.VARIABLE_CASE, createVariableInterceptor(caseInstance));
}
return result;
}
@ApiOperation(value = "Update a single variable on a case instance asynchronously", tags = { "Case Instance Variables" }, nickname = "updateCaseInstanceVariableAsync",
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 global variables can be set in a case instance.\n"
+ "NB: Swagger V2 specification doesn't 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
- Send a valid JSON RestVariable object with Content-Type: application/json, e.g. {"name":"x","value":5,"type":"integer"}.
- Validate the body parses as JSON before sending (e.g. JSON.parse in client code).
- Ensure no proxy/gateway is truncating or transforming the request body.
- If sending binary content, use the multipart form endpoint instead of the JSON body path.
Example fix
// before: invalid body
curl -X PUT .../variables/count -d 'count=5'
// after: proper RestVariable JSON
curl -X PUT .../variables/count -H 'Content-Type: application/json' -d '{"name":"count","value":5,"type":"integer"}' Defensive patterns
Strategy: validation
Validate before calling
const bodyJson = JSON.stringify({ name: variableName, value: value, type: typeof value === 'number' ? 'integer' : 'string' });
JSON.parse(bodyJson); // fail fast client-side if not valid JSON
// ensure header: 'Content-Type: application/json' Type guard
function isRestVariable(v) {
return v !== null && typeof v === 'object' && typeof v.name === 'string' && 'value' in v;
} Try / catch
try {
await updateCaseVariable(caseId, name, restVariable);
} catch (e) {
if (e.status === 400) { /* body wasn't a RestVariable: re-serialize and retry once */ }
else throw e;
} Prevention
- Always set Content-Type: application/json on non-multipart variable updates.
- Send a full RestVariable object, never a raw value.
- Log/verify the exact outgoing body when going through proxies or interceptors.
When it happens
Trigger: PUT /cmmn-runtime/case-instances/{id}/variables/{name} with a non-multipart request whose body is not valid JSON, is empty, has wrong Content-Type (e.g. form-encoded or missing application/json), or whose JSON structure doesn't map to RestVariable.
Common situations: Forgetting to set Content-Type: application/json; sending raw values (e.g. just '5') instead of a RestVariable JSON object; truncated bodies from proxies; clients sending XML or URL-encoded form data.
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
- Failed to serialize to a AttachmentRequest instance
- Error reading app resource
- Failed to serialize to a RestVariable instance
- Error converting request body to RestVariable instance
- Could not deserialize event to json
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/57ec626118348bc3.
Report an issue: GitHub.