{"record":{"id":"bb289f4fda14a221","repo":"flowable/flowable-engine","slug":"task-is-already-deleted","errorCode":null,"errorMessage":"{task} is already deleted","messagePattern":"(.+?) is already deleted","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/ActivateTaskCmd.java","lineNumber":55,"sourceCode":"        this.userId = userId;\n    }\n\n    @Override\n    public Void execute(CommandContext commandContext) {\n        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);\n        \n        if (taskId == null) {\n            throw new FlowableIllegalArgumentException(\"taskId is null\");\n        }\n\n        TaskEntity task = processEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);\n\n        if (task == null) {\n            throw new FlowableObjectNotFoundException(\"Cannot find task with id \" + taskId, Task.class);\n        }\n\n        if (task.isDeleted()) {\n            throw new FlowableException(task + \" is already deleted\");\n        }\n\n        if (!task.isSuspended()) {\n            throw new FlowableException(task + \" is not suspended, so can't be activated\");\n        }\n        \n        Clock clock = processEngineConfiguration.getClock();\n        Date updateTime = clock.getCurrentTime();\n        task.setSuspendedTime(null);\n        task.setSuspendedBy(null);\n        if (task.getInProgressStartTime() != null) {\n            task.setState(Task.IN_PROGRESS);\n        } else if (task.getClaimTime() != null) {\n            task.setState(Task.CLAIMED);\n        } else {\n            task.setState(Task.CREATED);\n        }\n        task.setSuspensionState(SuspensionState.ACTIVE.getStateCode());","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/ActivateTaskCmd.java#L37-L73","documentation":"State check in ActivateTaskCmd.execute: the task was found, but its deletion flag shows it has already been deleted, so (re)activating it is not allowed. The task row still exists (historically) but is no longer a live runtime task.","triggerScenarios":"taskService.activateTask(id) on a task whose process instance was deleted or whose task was removed concurrently between lookup and activation.","commonSituations":"Race condition where another thread/user deletes the process instance while a batch job suspends/activates tasks; retry logic re-running activation on already-deleted tasks.","solutions":["Query the task again before activation and skip if it no longer exists or is deleted.","Handle the exception gracefully for idempotent batch processing (treat 'already deleted' as success/skip).","Remove stale taskId entries from your scheduling store when the process instance is deleted.","Serialize suspension/activation operations for the same process instance to avoid races."],"exampleFix":"// before\ntaskService.activateTask(taskId); // may hit deleted task\n// after\nTask t = taskService.createTaskQuery().taskId(taskId).singleResult();\nif (t != null && !t.isDeleted() && t.isSuspended()) {\n    taskService.activateTask(taskId);\n}","handlingStrategy":"try-catch","validationCode":"Task t = taskService.createTaskQuery().taskId(taskId).singleResult();\nif (t == null || t.isDeleted() || !t.isSuspended()) {\n    return;\n}","typeGuard":null,"tryCatchPattern":"try {\n    taskService.activateTask(taskId);\n} catch (FlowableException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"already deleted\")) {\n        // treat as no-op in idempotent batch\n    } else {\n        throw e;\n    }\n}","preventionTips":["Make suspend/activate batch jobs idempotent.","Subscribe to entity-deleted events to purge pending task operations.","Avoid racing deletion and activation on the same instance."],"tags":["flowable","task","deleted","invalid-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}