{"record":{"id":"0365fa5e6d77d108","repo":"flowable/flowable-engine","slug":"a-request-body-was-expected-when-updating-the-task","errorCode":null,"errorMessage":"A request body was expected when updating the task.","messagePattern":"A request body was expected when updating the task\\.","errorType":"http","errorClass":"FlowableException","httpStatus":500,"severity":"error","filePath":"modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/task/TaskResource.java","lineNumber":80,"sourceCode":"            @ApiResponse(code = 404, message = \"Indicates the requested task was not found.\")\n    })\n    @GetMapping(value = \"/cmmn-runtime/tasks/{taskId}\", produces = \"application/json\")\n    public TaskResponse getTask(@ApiParam(name = \"taskId\") @PathVariable String taskId) {\n        return restResponseFactory.createTaskResponse(getTaskFromRequest(taskId));\n    }\n\n    @ApiOperation(value = \"Update a task\", tags = {\n            \"Tasks\" }, notes = \"All request values are optional. For example, you can only include the assignee attribute in the request body JSON-object, only updating the assignee of the task, leaving all other fields unaffected. When an attribute is explicitly included and is set to null, the task-value will be updated to null. Example: {\\\"dueDate\\\" : null} will clear the duedate of the task).\")\n    @ApiResponses(value = {\n            @ApiResponse(code = 200, message = \"Indicates the task was updated.\"),\n            @ApiResponse(code = 404, message = \"Indicates the requested task was not found.\"),\n            @ApiResponse(code = 409, message = \"Indicates the requested task was updated simultaneously.\")\n    })\n    @PutMapping(value = \"/cmmn-runtime/tasks/{taskId}\", produces = \"application/json\")\n    public TaskResponse updateTask(@ApiParam(name = \"taskId\") @PathVariable String taskId, @RequestBody TaskRequest taskRequest) {\n\n        if (taskRequest == null) {\n            throw new FlowableException(\"A request body was expected when updating the task.\");\n        }\n\n        Task task = getTaskFromRequestWithoutAccessCheck(taskId);\n\n        // Populate the task properties based on the request\n        populateTaskFromRequest(task, taskRequest);\n\n        if (restApiInterceptor != null) {\n            restApiInterceptor.updateTask(task, taskRequest);\n        }\n\n        // Save the task and fetch again, it's possible that an\n        // assignment-listener has updated\n        // fields after it was saved so we can't use the in-memory task\n        taskService.saveTask(task);\n        task = taskService.createTaskQuery().taskId(task.getId()).singleResult();\n\n        return restResponseFactory.createTaskResponse(task);","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/task/TaskResource.java#L62-L98","documentation":"PUT /cmmn-runtime/tasks/{taskId} expects a TaskRequest body describing the fields to update. Flowable throws a plain FlowableException if the deserialized body is null, i.e. the request was sent without a body or with an empty body.","triggerScenarios":"PUT to /cmmn-runtime/tasks/{taskId} with no request body, an empty body, or a Content-Type that prevents JSON deserialization into TaskRequest.","commonSituations":"Calling the endpoint with GET-style tooling that omits the body; forgetting to set Content-Type: application/json; proxies or clients stripping empty bodies; sending body as form data.","solutions":["Send a JSON body with the task fields to update, e.g. {\"name\":\"Reviewed\",\"description\":\"...\"}","Set the Content-Type: application/json header on the PUT request","Verify the HTTP client actually transmits the body (some clients omit it when no fields are set)"],"exampleFix":"// before\nrestTemplate.put(\"/cmmn-runtime/tasks/123\", null);\n// after\nHttpHeaders headers = new HttpHeaders();\nheaders.setContentType(MediaType.APPLICATION_JSON);\nrestTemplate.exchange(\"/cmmn-runtime/tasks/123\", HttpMethod.PUT,\n    new HttpEntity<>(Collections.singletonMap(\"name\", \"Reviewed\"), headers), TaskResponse.class);","handlingStrategy":"validation","validationCode":"function canUpdateTask(patch) {\n  return patch != null && typeof patch === 'object' && Object.keys(patch).length > 0;\n}","typeGuard":"function hasBody(b) {\n  return b != null && typeof b === 'object';\n}","tryCatchPattern":"try {\n  await put(`/cmmn-runtime/tasks/${taskId}`, patch);\n} catch (e) {\n  if (e.status === 500 && /request body was expected/.test(e.body.message)) {\n    throw new Error('PUT task requires a JSON body');\n  }\n  throw e;\n}","preventionTips":["Always set Content-Type: application/json on PUT requests","Assert the payload is serialized before sending","Avoid null bodies: send at least one updatable field"],"tags":["rest-api","request-body","task-update"],"backgroundTag":"empty-request-body","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}