flowable/flowable-engine · error · FlowableException
A request body was expected when bulk updating tasks.
Error message
A request body was expected when bulk updating tasks.
What it means
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.
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.
Example fix
// before
curl -X PUT http://host/flowable-rest/runtime/tasks
// after
curl -X PUT -H "Content-Type: application/json" -d '{"tasks":[{"id":"1"}],"action":"complete"}' http://host/flowable-rest/runtime/tasks Defensive patterns
Strategy: validation
Validate before calling
if (!body || Object.keys(body).length === 0) {
throw new Error('Bulk update requires a JSON request body');
} Type guard
function hasBulkBody(b) { return b != null && typeof b === 'object'; } Try / catch
try {
// PUT /runtime/tasks
} catch (e) {
if (String(e.message).includes('A request body was expected when bulk updating tasks')) {
// attach JSON body and retry once
} else throw e;
} Prevention
- 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
When it happens
Trigger: Sending PUT /runtime/tasks with no body, empty body, or wrong/missing Content-Type so Spring does not populate @RequestBody BulkTasksRequest.
Common situations: 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.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- A request body was expected when executing the form submit.
- Invalid body was supplied
- request body could not be transformed to a RestVariable…
- taskIds can not be null for bulk update tasks requests
- A request body was expected when bulk updating tasks.
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/da94521ea6721559.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-rest/src/main/java/org/flowable/rest/service/api/runtime/task/TaskCollectionResource.java:415
if (restApiInterceptor != null) {
restApiInterceptor.createTask(task, taskRequest);
}
taskService.saveTask(task);
return restResponseFactory.createTaskResponse(task);
}
@ApiOperation(value = "Update Tasks", tags = { "Tasks" })
@ApiResponses(value = {
@ApiResponse(code = 201, message = "Indicates request was successful and the tasks are returned"),
@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.")
})
@PutMapping(value = "/runtime/tasks", produces = "application/json")
public DataResponse<TaskResponse> bulkUpdateTasks(@RequestBody BulkTasksRequest bulkTasksRequest) {
if (bulkTasksRequest == null) {
throw new FlowableException("A request body was expected when bulk updating tasks.");
}
if (bulkTasksRequest.getTaskIds() == null) {
throw new FlowableIllegalArgumentException("taskIds can not be null for bulk update tasks requests");
}
Collection<Task> taskList = getTasksFromIdList(bulkTasksRequest.getTaskIds());
if (taskList.size() != bulkTasksRequest.getTaskIds().size()) {
taskList.stream().forEach(task -> bulkTasksRequest.getTaskIds().remove(task.getId()));
throw new FlowableObjectNotFoundException(
"Could not find task instance with id:" + bulkTasksRequest.getTaskIds().stream().collect(Collectors.joining(",")));
}
// Populate the task properties based on the request
populateTasksFromRequest(taskList, bulkTasksRequest);
if (restApiInterceptor != null) {
restApiInterceptor.bulkUpdateTasks(taskList, bulkTasksRequest);View on GitHub (pinned to d6d39ce1c6)