{"record":{"id":"f0d550c398c7cb38","repo":"flowable/flowable-engine","slug":"the-task-cannot-be-deleted-because-is-part-of-a-f0d550","errorCode":null,"errorMessage":"The ${task} cannot be deleted because is part of a running process instance","messagePattern":"The (.+?) cannot be deleted because is part of a running process instance","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/task/TaskHelper.java","lineNumber":76,"sourceCode":"        if (taskEntity.getAssignee() != null) {\n            addAssigneeIdentityLinks(taskEntity, cmmnEngineConfiguration);\n            fireAssignmentEvents(taskEntity, cmmnEngineConfiguration);\n        }\n\n    }\n    \n    public static void completeTask(TaskEntity task, String userId, CmmnEngineConfiguration cmmnEngineConfiguration) {\n        cmmnEngineConfiguration.getPlanItemInstanceEntityManager().updateHumanTaskPlanItemInstanceCompletedBy(task, userId);\n        internalDeleteTask(task, userId, null, false, true, cmmnEngineConfiguration);\n    }\n\n    public static void deleteTask(String taskId, String deleteReason, boolean cascade, CmmnEngineConfiguration cmmnEngineConfiguration) {\n        TaskEntity task = cmmnEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);\n        if (task != null) {\n            if (task.getScopeId() != null && ScopeTypes.CMMN.equals(task.getScopeType())) {\n                throw new FlowableException(\"The \" + task + \" cannot be deleted because is part of a running case instance\");\n            } else if (task.getExecutionId() != null) {\n                throw new FlowableException(\"The \" + task + \" cannot be deleted because is part of a running process instance\");\n            }\n            deleteTask(task, deleteReason, cascade, true, cmmnEngineConfiguration);\n            \n        } else if (cascade) {\n            deleteHistoricTask(taskId, cmmnEngineConfiguration);\n        }\n    }\n    \n    public static void deleteTask(TaskEntity task, String deleteReason, boolean cascade, \n            boolean fireEvents, CmmnEngineConfiguration cmmnEngineConfiguration) {\n        \n        internalDeleteTask(task, null, deleteReason, cascade, fireEvents, cmmnEngineConfiguration);\n    }\n\n    protected static void internalDeleteTask(TaskEntity task, String userId, String deleteReason, boolean cascade, \n            boolean fireEvents, CmmnEngineConfiguration cmmnEngineConfiguration) {\n        \n        if (!task.isDeleted()) {","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/task/TaskHelper.java#L58-L94","documentation":"The process-instance twin of error 932: TaskHelper.deleteTask throws this when the task has an executionId, meaning it belongs to a running BPMN process instance. The engine manages such tasks' lifecycle; direct deletion is forbidden to keep execution and history consistent.","triggerScenarios":"Calling TaskService.deleteTask / TaskHelper.deleteTask on a task whose getExecutionId() != null, i.e. a user task created inside an active process instance (and not CMMN-scoped, which would hit the case variant first).","commonSituations":"Task cleanup scripts and admin endpoints deleting 'stuck' tasks that are actually process user tasks; tests deleting seeded tasks without terminating the process; shared task-delete code paths reused across BPMN and CMMN.","solutions":["Delete the owning process instance instead (RuntimeService.deleteProcessInstance(executionId, reason)) so the engine cascades task deletion","Skip execution-linked tasks in cleanup code by checking task.getExecutionId() != null before deleting","If the process should continue but the task must go, remove the underlying activity/plan appropriately (e.g. change activity state or complete the task) rather than deleteTask","For finished instances, purge via history services instead"],"exampleFix":"// before\ntaskService.deleteTask(taskId, \"cleanup\");\n// after\nTaskEntity task = ...getTask(taskId);\nif (task.getExecutionId() != null) {\n    runtimeService.deleteProcessInstance(task.getProcessInstanceId(), \"cleanup\");\n} else {\n    taskService.deleteTask(taskId, \"cleanup\");\n}","handlingStrategy":"validation","validationCode":"if (task.getExecutionId() != null) {\n    throw new IllegalArgumentException(\"task \" + task.getId() + \" belongs to process \" + task.getProcessInstanceId() + \"; delete the process instead\");\n}","typeGuard":"boolean isProcessTask(Task t) { return t.getExecutionId() != null; }","tryCatchPattern":"try { taskService.deleteTask(taskId, reason); } catch (FlowableException e) { if (e.getMessage().contains(\"running process instance\")) { runtimeService.deleteProcessInstance(task.getProcessInstanceId(), reason); } else throw e; }","preventionTips":["Check executionId before deleting any task","Route cleanup jobs through runtime service deletions","Complete or remove user tasks via process operations, not deleteTask"],"tags":["bpmn","task-lifecycle","flowable"],"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-14T05:17:10.506Z"}