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
- Skip tasks whose state indicates deletion; re-query the task right before activation and bail out if deleted or absent
- Handle the FlowableException (message "Task <id> is already deleted") idempotently in worker code
- Check the parent case instance state before activating its tasks
- 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
- Check the parent case instance state before activating its tasks
- Re-read the task immediately before activation to shrink race windows
- Make bulk activation idempotent against deleted tasks
- Match on the exception message carefully — this error uses FlowableException, not a typed not-found/illegal-argument class
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
- taskId is null
- Cannot find task with id ${taskId}
- task ${taskId} doesn't exist
- 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/b95a6ed68d3f2bca.
Report an issue: GitHub.