flowable/flowable-engine · error · FlowableException

Task ${taskId} is already deleted

Error message

Task ${taskId} is already deleted

What it means

Plain FlowableException thrown by ActivateTaskCmd.execute when the task exists but is already marked deleted (task.isDeleted()). Activation is only meaningful for suspended live tasks; a deleted task cannot be re-activated, so the command fails fast. This typically indicates the case instance was terminated and the task was cascaded to deleted.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/ActivateTaskCmd.java:58

        this.userId = userId;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
        
        if (taskId == null) {
            throw new FlowableIllegalArgumentException("taskId is null");
        }

        TaskEntity task = cmmnEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);

        if (task == null) {
            throw new FlowableObjectNotFoundException("Cannot find task with id " + taskId, Task.class);
        }

        if (task.isDeleted()) {
            throw new FlowableException("Task " + taskId + " is already deleted");
        }

        if (!task.isSuspended()) {
            throw new FlowableException("Task " + taskId + " is not suspended, so can't be activated");
        }
        
        Clock clock = cmmnEngineConfiguration.getClock();
        Date updateTime = clock.getCurrentTime();
        task.setSuspendedTime(null);
        task.setSuspendedBy(null);
        if (task.getInProgressStartTime() != null) {
            task.setState(Task.IN_PROGRESS);
        } else if (task.getClaimTime() != null) {
            task.setState(Task.CLAIMED);
        } else {
            task.setState(Task.CREATED);
        }
        task.setSuspensionState(SuspensionState.ACTIVE.getStateCode());

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Skip tasks whose state indicates deletion; re-query the task right before activation and bail out if deleted or absent
  2. Handle the FlowableException (message "Task <id> is already deleted") idempotently in worker code
  3. Check the parent case instance state before activating its tasks
  4. Avoid re-running activation batches over completed/terminated cases

Example fix

// before
cmmnTaskService.activateTask(taskId); // throws if task deleted
// after
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task != null && task.isSuspended() && !task.isDeleted()) {
    cmmnTaskService.activateTask(taskId);
} else {
    logger.info("Task {} not activatable (missing/suspended/deleted); skipping", taskId);
}
Defensive patterns

Strategy: validation

Validate before calling

Task t = taskService.createTaskQuery().taskId(taskId).singleResult();
if (t == null || t.isDeleted()) throw new IllegalStateException("Task " + taskId + " is deleted or missing; cannot activate");

Try / catch

try { cmmnTaskService.activateTask(taskId); }
catch (FlowableException e) { if (e.getMessage() != null && e.getMessage().endsWith("is already deleted")) { log.info("Task {} already deleted; skipping", taskId); } else { throw e; } }

Prevention

When it happens

Trigger: Calling activateTask on a task belonging to a terminated/completed case instance whose tasks were deleted; a concurrent delete completed between the task lookup and the isDeleted check; activating tasks after the case ended.

Common situations: Bulk activation scripts running after a case was terminated elsewhere; race between a user terminating a case and a worker activating its suspended tasks; retry logic replaying activation for tasks removed by cleanup.

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