flowable/flowable-engine · error · FlowableException
The ${task} cannot be deleted because is part of a running p
Error message
The ${task} cannot be deleted because is part of a running process What it means
TaskHelper.deleteTask throws this when the task is still attached to a process execution (task.getExecutionId() != null). Standalone task deletion is only allowed for tasks that do not belong to a running process instance; such tasks' lifecycle is owned by the process.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/TaskHelper.java:572
}
protected static void fireTaskDeletedEvent(TaskEntity task, CommandContext commandContext, FlowableEventDispatcher eventDispatcher) {
if (eventDispatcher != null && eventDispatcher.isEnabled()) {
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
CommandContextUtil.getEventDispatcher(commandContext).dispatchEvent(
FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_DELETED, task),
processEngineConfiguration.getEngineCfgKey());
}
}
public static void deleteTask(String taskId, String deleteReason, boolean cascade) {
CommandContext commandContext = CommandContextUtil.getCommandContext();
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
TaskEntity task = processEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);
if (task != null) {
if (task.getExecutionId() != null) {
throw new FlowableException("The " + task + " cannot be deleted because is part of a running process");
} else if (task.getScopeId() != null && ScopeTypes.CMMN.equals(task.getScopeType())) {
throw new FlowableException("The " + task + " cannot be deleted because is part of a running case");
}
if (Flowable5Util.isFlowable5ProcessDefinitionId(commandContext, task.getProcessDefinitionId())) {
Flowable5CompatibilityHandler compatibilityHandler = Flowable5Util.getFlowable5CompatibilityHandler();
compatibilityHandler.deleteTask(taskId, deleteReason, cascade);
return;
}
deleteTask(task, deleteReason, cascade, true, true);
} else if (cascade) {
deleteHistoricTask(taskId);
}
}
public static void deleteTasksByProcessInstanceId(String processInstanceId, String deleteReason, boolean cascade) {View on GitHub (pinned to d6d39ce1c6)
Solutions
- Only delete standalone tasks: query with taskService.createTaskQuery().taskId(id).processInstanceIdUnspecified() or check task.getProcessInstanceId() == null first.
- To remove an in-process task, end it via taskService.completeTask or change the process (boundary event / process instance cancellation).
- Cancel the whole process instance via runtimeService.deleteProcessInstance(pid, reason) if the intent is cleanup.
- If cascade removal is needed, use deleteTask(taskId, true) only where legitimate; this error still blocks execution-bound tasks.
Example fix
// before
taskService.deleteTask(taskId, "cleanup");
// after
Task t = taskService.createTaskQuery().taskId(taskId).singleResult();
if (t != null && t.getProcessInstanceId() == null) {
taskService.deleteTask(taskId, "cleanup");
} else {
runtimeService.deleteProcessInstance(t.getProcessInstanceId(), "cleanup");
} Defensive patterns
Strategy: validation
Validate before calling
Task t = taskService.createTaskQuery().taskId(taskId).singleResult(); boolean deletable = t != null && t.getExecutionId() == null && !ScopeTypes.CMMN.equals(t.getScopeType());
Type guard
boolean isStandaloneTask(Task t) { return t != null && t.getExecutionId() == null && t.getProcessInstanceId() == null; } Try / catch
try { taskService.deleteTask(taskId, reason); } catch (FlowableException e) { log.warn("Task {} is process-bound: {}", taskId, e.getMessage()); } Prevention
- Query only standalone tasks with .processInstanceIdUnspecified() before deleting
- Never bulk-delete tasks without filtering executionId/scopeType
- Prefer ending/canceling the process instead of deleting its tasks
When it happens
Trigger: Calling TaskService.deleteTask(taskId) (or deleteTasks) with the id of a task that has an executionId, i.e. a user task inside a running BPMN process instance.
Common situations: Admin cleanup scripts iterating all tasks including in-process ones; deleting tasks fetched without filtering on processInstanceId being null; trying to remove a stale-looking user task that is actually part of an active workflow.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- A delegated ${taskEntity} cannot be completed, but should be
- The ${task} cannot be deleted because is part of a running c
- Cannot resume task with id '
- No task associated. Call businessProcess.startTask() first.
- taskId is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/8ed1fd1eb04b671c.
Report an issue: GitHub.