flowable/flowable-engine · error · FlowableForbiddenException
Cannot delete a task that is part of a process instance.
Error message
Cannot delete a task that is part of a process instance.
What it means
The CMMN REST task endpoint also rejects deleting a task that is attached to a BPMN process instance (task has a non-null executionId). Even though this is the CMMN REST module, shared tasks with process scope are protected the same way: the engine owns their lifecycle. FlowableForbiddenException (HTTP 403) is thrown.
Source
Thrown at modules/flowable-cmmn-rest/src/main/java/org/flowable/cmmn/rest/service/api/runtime/task/TaskResource.java:162
@ApiImplicitParam(name = "cascadeHistory", dataType = "string", value = "Whether or not to delete the HistoricTask instance when deleting the task (if applicable). If not provided, this value defaults to false.", paramType = "query"),
@ApiImplicitParam(name = "deleteReason", dataType = "string", value = "Reason why the task is deleted. This value is ignored when cascadeHistory is true.", paramType = "query")
})
@ApiResponses(value = {
@ApiResponse(code = 204, message = "Indicates the task was found and has been deleted. Response-body is intentionally empty."),
@ApiResponse(code = 403, message = "Indicates the requested task cannot be deleted because it’s part of a workflow."),
@ApiResponse(code = 404, message = "Indicates the requested task was not found.")
})
@DeleteMapping(value = "/cmmn-runtime/tasks/{taskId}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteTask(@ApiParam(name = "taskId") @PathVariable String taskId, @ApiParam(hidden = true) @RequestParam(value = "cascadeHistory", required = false) Boolean cascadeHistory,
@ApiParam(hidden = true) @RequestParam(value = "deleteReason", required = false) String deleteReason) {
Task taskToDelete = getTaskFromRequestWithoutAccessCheck(taskId);
if (taskToDelete.getScopeId() != null && ScopeTypes.CMMN.equals(taskToDelete.getScopeType())) {
// Can't delete a task that is part of a case instance
throw new FlowableForbiddenException("Cannot delete a task that is part of a case instance.");
} else if (taskToDelete.getExecutionId() != null) {
throw new FlowableForbiddenException("Cannot delete a task that is part of a process instance.");
}
if (restApiInterceptor != null) {
restApiInterceptor.deleteTask(taskToDelete);
}
if (cascadeHistory != null) {
// Ignore delete-reason since the task-history (where the reason is
// recorded) will be deleted anyway
taskService.deleteTask(taskToDelete.getId(), cascadeHistory);
} else {
// Delete with delete-reason
taskService.deleteTask(taskToDelete.getId(), deleteReason);
}
}
@ApiOperation(value = "Get a task form", tags = { "Tasks" })
@ApiResponses(value = {View on GitHub (pinned to d6d39ce1c6)
Solutions
- Complete the task (POST action 'complete') or end the process instance instead of deleting it.
- Delete the process instance via the process REST API (DELETE /runtime/process-instances/{id}) if the whole instance should go.
- Skip tasks with a non-null executionId in deletion scripts.
- Use the correct REST module (flowable-rest process endpoints) for process-scoped task operations.
Example fix
// before
curl -X DELETE /flowable-rest/cmmn-runtime/tasks/123
// throws: Cannot delete a task that is part of a process instance.
// after
curl -X POST /flowable-rest/cmmn-runtime/tasks/123 -H 'Content-Type: application/json' -d '{"action":"complete"}' Defensive patterns
Strategy: type-guard
Validate before calling
const task = await api.get(`/cmmn-runtime/tasks/${id}`);
if (task.executionId) throw new Error('task belongs to a process instance; use process APIs'); Type guard
function isProcessTask(t) { return !!t.executionId; } Try / catch
try { await api.delete(`/cmmn-runtime/tasks/${id}`); } catch (e) { if (e.response && e.response.status === 403) { /* route to process instance cleanup */ } else { throw e; } } Prevention
- Skip tasks with non-null executionId in cleanup jobs
- Use the process REST module for process-scoped tasks
- Complete tasks rather than deleting engine-managed tasks
When it happens
Trigger: Calling DELETE /cmmn-runtime/tasks/{taskId} where taskToDelete.getExecutionId() != null, i.e. the task was created by a running BPMN process but accessed through the CMMN REST API.
Common situations: Mixing the process and case REST APIs against a shared task; cleanup jobs iterating tasks without checking executionId; deleting a user task that belongs to an active process instance.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Cannot delete a task that is part of a case instance.
- Cannot delete a task that is part of a case instance.
- No execution could be found for id {executionId}
- Task ${taskId} is not suspended, so can't be activated
- is created by the process engine and should be completed vi
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/c3d032a6776fcf28.
Report an issue: GitHub.