{"record":{"id":"da94521ea6721559","repo":"flowable/flowable-engine","slug":"a-request-body-was-expected-when-bulk-updating-tas-da9452","errorCode":null,"errorMessage":"A request body was expected when bulk updating tasks.","messagePattern":"A request body was expected when bulk updating tasks\\.","errorType":"http","errorClass":"FlowableException","httpStatus":400,"severity":"error","filePath":"modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/task/TaskCollectionResource.java","lineNumber":415,"sourceCode":"        if (restApiInterceptor != null) {\n            restApiInterceptor.createTask(task, taskRequest);\n        }\n        \n        taskService.saveTask(task);\n\n        return restResponseFactory.createTaskResponse(task);\n    }\n\n    @ApiOperation(value = \"Update Tasks\", tags = { \"Tasks\" })\n    @ApiResponses(value = {\n            @ApiResponse(code = 201, message = \"Indicates request was successful and the tasks are returned\"),\n            @ApiResponse(code = 400, message = \"Indicates a parameter was passed in the wrong format or that delegationState has an invalid value (other than pending and resolved). The status-message contains additional information.\")\n    })\n    @PutMapping(value = \"/runtime/tasks\", produces = \"application/json\")\n    public DataResponse<TaskResponse> bulkUpdateTasks(@RequestBody BulkTasksRequest bulkTasksRequest) {\n\n        if (bulkTasksRequest == null) {\n            throw new FlowableException(\"A request body was expected when bulk updating tasks.\");\n        }\n        if (bulkTasksRequest.getTaskIds() == null) {\n            throw new FlowableIllegalArgumentException(\"taskIds can not be null for bulk update tasks requests\");\n        }\n\n        Collection<Task> taskList = getTasksFromIdList(bulkTasksRequest.getTaskIds());\n\n        if (taskList.size() != bulkTasksRequest.getTaskIds().size()) {\n            taskList.stream().forEach(task -> bulkTasksRequest.getTaskIds().remove(task.getId()));\n            throw new FlowableObjectNotFoundException(\n                    \"Could not find task instance with id:\" + bulkTasksRequest.getTaskIds().stream().collect(Collectors.joining(\",\")));\n        }\n\n        // Populate the task properties based on the request\n        populateTasksFromRequest(taskList, bulkTasksRequest);\n\n        if (restApiInterceptor != null) {\n            restApiInterceptor.bulkUpdateTasks(taskList, bulkTasksRequest);","sourceCodeStart":397,"sourceCodeEnd":433,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/task/TaskCollectionResource.java#L397-L433","documentation":"Flowable's REST PUT /runtime/tasks (bulkUpdateTasks) throws FlowableException when the request body is missing entirely. The BulkTasksRequest parameter cannot be bound without a body, and the endpoint requires task ids plus the updates to apply.","triggerScenarios":"Sending PUT /runtime/tasks with no body, empty body, or wrong/missing Content-Type so Spring does not populate @RequestBody BulkTasksRequest.","commonSituations":"REST clients omitting Content-Type: application/json, sending GET-style requests with no payload, proxies stripping the body, or hand-crafted curl commands missing -d/--data.","solutions":["Send a JSON body such as {\"tasks\":[...], \"action\":...} with PUT /runtime/tasks.","Set the Content-Type: application/json header on the request.","In curl, pass the payload with -d '{...}' (and -H \"Content-Type: application/json\").","Check client code that the bulk-update call actually attaches the request object, not null."],"exampleFix":"// before\ncurl -X PUT http://host/flowable-rest/runtime/tasks\n// after\ncurl -X PUT -H \"Content-Type: application/json\" -d '{\"tasks\":[{\"id\":\"1\"}],\"action\":\"complete\"}' http://host/flowable-rest/runtime/tasks","handlingStrategy":"validation","validationCode":"if (!body || Object.keys(body).length === 0) {\n    throw new Error('Bulk update requires a JSON request body');\n}","typeGuard":"function hasBulkBody(b) { return b != null && typeof b === 'object'; }","tryCatchPattern":"try {\n    // PUT /runtime/tasks\n} catch (e) {\n    if (String(e.message).includes('A request body was expected when bulk updating tasks')) {\n        // attach JSON body and retry once\n    } else throw e;\n}","preventionTips":["Always set Content-Type: application/json","Verify the HTTP client actually sends the body (check with logging/proxy)","Include -d in curl commands for PUT requests"],"tags":["rest-api","flowable","http","request-body"],"backgroundTag":"missing-required-argument","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"}