flowable/flowable-engine · error · FlowableException
The ${task} cannot be deleted because is part of a running c
Error message
The ${task} cannot be deleted because is part of a running case What it means
Same guard as the running-process case but for CMMN: TaskHelper.deleteTask throws when the task's scopeType is 'cmmn' and it has a scopeId, i.e. it belongs to a running case instance. Its lifecycle is controlled by the case engine, so direct deletion is rejected.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/TaskHelper.java:574
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) {
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
List<TaskEntity> tasks = processEngineConfiguration.getTaskServiceConfiguration().getTaskService().findTasksByProcessInstanceId(processInstanceId);View on GitHub (pinned to d6d39ce1c6)
Solutions
- Check task.getScopeType() before deleting and skip CMMN-scoped tasks.
- End the task through the CMMN engine (complete it or terminate the case stage) instead of direct deletion.
- Terminate the case instance via the CMMN runtime service (caseRuntimeService.terminateCaseInstance) if cleanup is the goal.
- Filter task queries with taskCandidateOrAssigned without CMMN scope or add scopeType filters before performing deletions.
Example fix
// before
taskService.deleteTask(taskId, "cleanup");
// after
Task t = taskService.createTaskQuery().taskId(taskId).singleResult();
if (t != null && !ScopeTypes.CMMN.equals(t.getScopeType())) {
taskService.deleteTask(taskId, "cleanup");
} Defensive patterns
Strategy: validation
Validate before calling
Task t = taskService.createTaskQuery().taskId(taskId).singleResult(); boolean deletable = t != null && !ScopeTypes.CMMN.equals(t.getScopeType());
Type guard
boolean isCmmnTask(Task t) { return t != null && ScopeTypes.CMMN.equals(t.getScopeType()); } Try / catch
try { taskService.deleteTask(taskId, reason); } catch (FlowableException e) { if (e.getMessage().contains("running case")) { /* route to CMMN engine */ } else throw e; } Prevention
- Always check scopeType in mixed BPMN/CMMN deployments
- Handle CMMN tasks via the case runtime service, not TaskService.deleteTask
- Exclude scoped tasks from cleanup jobs
When it happens
Trigger: Calling TaskService.deleteTask(taskId) on a task whose scopeId is set and scopeType is ScopeTypes.CMMN (a human task created by a running CMMN case).
Common situations: Deleting tasks in shared task lists without checking scopeType; cleanup jobs that assume all tasks are BPMN standalone tasks; mixed BPMN/CMMN deployments where CMMN-originated tasks slip through.
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
- taskId is null
- Cannot find task with id ${taskId}
- Task ${taskId} is already deleted
- task ${taskId} doesn't exist
- task ${taskId} doesn't exist
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/dafa27d2e87d979d.
Report an issue: GitHub.