flowable/flowable-engine · error · ActivitiException

The task cannot be deleted because is part of a running proc

Error message

The task cannot be deleted because is part of a running process

What it means

TaskEntityManager.deleteTask(taskId, ...) refuses to delete a standalone task whose executionId is not null, because such a task belongs to a running process instance and its lifecycle is owned by the engine. Deleting it directly would corrupt the process state, so the engine throws this ActivitiException. Only standalone tasks (created via TaskService.newTask) may be deleted through this path; process tasks disappear when their execution completes or the instance is deleted.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/persistence/entity/TaskEntityManager.java:202

    public long findTaskCountByNativeQuery(Map<String, Object> parameterMap) {
        return (Long) getDbSqlSession().selectOne("selectTaskCountByNativeQuery", parameterMap);
    }

    @SuppressWarnings("unchecked")
    public List<Task> findTasksByParentTaskId(String parentTaskId) {
        return getDbSqlSession().selectList("selectTasksByParentTaskId", parentTaskId);
    }

    public void deleteTask(String taskId, String deleteReason, boolean cascade) {
        TaskEntity task = Context
                .getCommandContext()
                .getTaskEntityManager()
                .findTaskById(taskId);

        if (task != null) {
            if (task.getExecutionId() != null) {
                throw new ActivitiException("The task cannot be deleted because is part of a running process");
            }

            String reason = (deleteReason == null || deleteReason.length() == 0) ? TaskEntity.DELETE_REASON_DELETED : deleteReason;
            deleteTask(task, reason, cascade);
        } else if (cascade) {
            Context
                    .getCommandContext()
                    .getHistoricTaskInstanceEntityManager()
                    .deleteHistoricTaskInstanceById(taskId);
        }
    }

    public void updateTaskTenantIdForDeployment(String deploymentId, String newTenantId) {
        HashMap<String, Object> params = new HashMap<>();
        params.put("deploymentId", deploymentId);
        params.put("tenantId", newTenantId);
        getDbSqlSession().update("updateTaskTenantIdForDeployment", params);
    }

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Delete the owning process instance instead: runtimeService.deleteProcessInstance(executionId, reason)
  2. Complete the task (or resolve and complete) rather than deleting it
  3. Use runtimeService.createChangeActivityStateBuilder() or move activity to a terminate end event to legally remove the activity
  4. Only call deleteTask on standalone tasks (executionId == null)

Example fix

// before
taskService.deleteTask(taskId); // throws for process tasks
// after
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task.getExecutionId() != null) {
    runtimeService.deleteProcessInstance(task.getProcessInstanceId(), "cancelled by admin");
} else {
    taskService.deleteTask(taskId);
}
Defensive patterns

Strategy: validation

Validate before calling

Task t = taskService.createTaskQuery().taskId(taskId).singleResult();
boolean deletable = t != null && t.getExecutionId() == null;

Try / catch

try {
    taskService.deleteTask(taskId);
} catch (ActivitiException e) {
    if (e.getMessage().contains("part of a running process")) {
        runtimeService.deleteProcessInstance(processInstanceId, reason);
    }
}

Prevention

When it happens

Trigger: Calling taskService.deleteTask(taskId) (or deleteTasks) where the task was created by a process (user task in a running process instance), detected via task.getExecutionId() != null.

Common situations: Admin cleanup scripts trying to remove stale user tasks from active process instances; trying to 'cancel' a task instead of completing it or deleting the process instance; tests deleting seeded process tasks.

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/b0bc0889656fae3f. Report an issue: GitHub.