{"record":{"id":"57ec626118348bc3","repo":"flowable/flowable-engine","slug":"request-body-could-not-be-transformed-to-a-restvar","errorCode":null,"errorMessage":"request body could not be transformed to a RestVariable instance.","messagePattern":"request body could not be transformed to a RestVariable instance\\.","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":409,"severity":"error","filePath":"modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/caze/CaseInstanceVariableResource.java","lineNumber":108,"sourceCode":"            HttpServletRequest request) {\n\n        CaseInstance caseInstance = getCaseInstanceFromRequestWithoutAccessCheck(caseInstanceId);\n\n        RestVariable result = null;\n        if (request instanceof MultipartHttpServletRequest) {\n            result = setBinaryVariable((MultipartHttpServletRequest) request, caseInstance.getId(), CmmnRestResponseFactory.VARIABLE_CASE, false,\n                    false, RestVariable.RestVariableScope.GLOBAL, createVariableInterceptor(caseInstance));\n\n            if (!result.getName().equals(variableName)) {\n                throw new FlowableIllegalArgumentException(\"Variable name in the body should be equal to the name used in the requested URL.\");\n            }\n\n        } else {\n            RestVariable restVariable = null;\n            try {\n                restVariable = objectMapper.readValue(request.getInputStream(), RestVariable.class);\n            } catch (Exception e) {\n                throw new FlowableIllegalArgumentException(\"request body could not be transformed to a RestVariable instance.\", e);\n            }\n\n            if (restVariable == null) {\n                throw new FlowableException(\"Invalid body was supplied\");\n            }\n            if (!restVariable.getName().equals(variableName)) {\n                throw new FlowableIllegalArgumentException(\"Variable name in the body should be equal to the name used in the requested URL.\");\n            }\n\n            result = setSimpleVariable(restVariable, caseInstance.getId(), false, false, RestVariable.RestVariableScope.GLOBAL, CmmnRestResponseFactory.VARIABLE_CASE, createVariableInterceptor(caseInstance));\n        }\n        return result;\n    }\n    \n    @ApiOperation(value = \"Update a single variable on a case instance asynchronously\", tags = { \"Case Instance Variables\" }, nickname = \"updateCaseInstanceVariableAsync\",\n            notes = \"This endpoint can be used in 2 ways: By passing a JSON Body (RestVariable) or by passing a multipart/form-data Object.\\n\"\n                    + \"Note that scope is ignored, only global variables can be set in a case instance.\\n\"\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.\")","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/caze/CaseInstanceVariableResource.java#L90-L126","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: invalid body\ncurl -X PUT .../variables/count -d 'count=5'\n// after: proper RestVariable JSON\ncurl -X PUT .../variables/count -H 'Content-Type: application/json' -d '{\"name\":\"count\",\"value\":5,\"type\":\"integer\"}'","handlingStrategy":"validation","validationCode":"const bodyJson = JSON.stringify({ name: variableName, value: value, type: typeof value === 'number' ? 'integer' : 'string' });\nJSON.parse(bodyJson); // fail fast client-side if not valid JSON\n// ensure header: 'Content-Type: application/json'","typeGuard":"function isRestVariable(v) {\n  return v !== null && typeof v === 'object' && typeof v.name === 'string' && 'value' in v;\n}","tryCatchPattern":"try {\n  await updateCaseVariable(caseId, name, restVariable);\n} catch (e) {\n  if (e.status === 400) { /* body wasn't a RestVariable: re-serialize and retry once */ }\n  else throw e;\n}","preventionTips":["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."],"tags":["rest-api","json","deserialization","request-body","flowable"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}