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

  1. Check task.getScopeType() before deleting and skip CMMN-scoped tasks.
  2. End the task through the CMMN engine (complete it or terminate the case stage) instead of direct deletion.
  3. Terminate the case instance via the CMMN runtime service (caseRuntimeService.terminateCaseInstance) if cleanup is the goal.
  4. 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

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


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/dafa27d2e87d979d. Report an issue: GitHub.