{"record":{"id":"8ed1fd1eb04b671c","repo":"flowable/flowable-engine","slug":"the-task-cannot-be-deleted-because-is-part-of-a-8ed1fd","errorCode":null,"errorMessage":"The ${task} cannot be deleted because is part of a running process","messagePattern":"The (.+?) cannot be deleted because is part of a running process","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/TaskHelper.java","lineNumber":572,"sourceCode":"    }\n\n    protected static void fireTaskDeletedEvent(TaskEntity task, CommandContext commandContext, FlowableEventDispatcher eventDispatcher) {\n        if (eventDispatcher != null && eventDispatcher.isEnabled()) {\n            ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);\n            CommandContextUtil.getEventDispatcher(commandContext).dispatchEvent(\n                    FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.ENTITY_DELETED, task),\n                    processEngineConfiguration.getEngineCfgKey());\n        }\n    }\n\n    public static void deleteTask(String taskId, String deleteReason, boolean cascade) {\n        CommandContext commandContext = CommandContextUtil.getCommandContext();\n        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);\n        TaskEntity task = processEngineConfiguration.getTaskServiceConfiguration().getTaskService().getTask(taskId);\n\n        if (task != null) {\n            if (task.getExecutionId() != null) {\n                throw new FlowableException(\"The \" + task + \" cannot be deleted because is part of a running process\");\n            } else 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\");\n            }\n\n            if (Flowable5Util.isFlowable5ProcessDefinitionId(commandContext, task.getProcessDefinitionId())) {\n                Flowable5CompatibilityHandler compatibilityHandler = Flowable5Util.getFlowable5CompatibilityHandler();\n                compatibilityHandler.deleteTask(taskId, deleteReason, cascade);\n                return;\n            }\n\n            deleteTask(task, deleteReason, cascade, true, true);\n\n        } else if (cascade) {\n            deleteHistoricTask(taskId);\n        }\n    }\n\n    public static void deleteTasksByProcessInstanceId(String processInstanceId, String deleteReason, boolean cascade) {","sourceCodeStart":554,"sourceCodeEnd":590,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/TaskHelper.java#L554-L590","documentation":"TaskHelper.deleteTask throws this when the task is still attached to a process execution (task.getExecutionId() != null). Standalone task deletion is only allowed for tasks that do not belong to a running process instance; such tasks' lifecycle is owned by the process.","triggerScenarios":"Calling TaskService.deleteTask(taskId) (or deleteTasks) with the id of a task that has an executionId, i.e. a user task inside a running BPMN process instance.","commonSituations":"Admin cleanup scripts iterating all tasks including in-process ones; deleting tasks fetched without filtering on processInstanceId being null; trying to remove a stale-looking user task that is actually part of an active workflow.","solutions":["Only delete standalone tasks: query with taskService.createTaskQuery().taskId(id).processInstanceIdUnspecified() or check task.getProcessInstanceId() == null first.","To remove an in-process task, end it via taskService.completeTask or change the process (boundary event / process instance cancellation).","Cancel the whole process instance via runtimeService.deleteProcessInstance(pid, reason) if the intent is cleanup.","If cascade removal is needed, use deleteTask(taskId, true) only where legitimate; this error still blocks execution-bound tasks."],"exampleFix":"// before\ntaskService.deleteTask(taskId, \"cleanup\");\n// after\nTask t = taskService.createTaskQuery().taskId(taskId).singleResult();\nif (t != null && t.getProcessInstanceId() == null) {\n    taskService.deleteTask(taskId, \"cleanup\");\n} else {\n    runtimeService.deleteProcessInstance(t.getProcessInstanceId(), \"cleanup\");\n}","handlingStrategy":"validation","validationCode":"Task t = taskService.createTaskQuery().taskId(taskId).singleResult();\nboolean deletable = t != null && t.getExecutionId() == null && !ScopeTypes.CMMN.equals(t.getScopeType());","typeGuard":"boolean isStandaloneTask(Task t) { return t != null && t.getExecutionId() == null && t.getProcessInstanceId() == null; }","tryCatchPattern":"try { taskService.deleteTask(taskId, reason); } catch (FlowableException e) { log.warn(\"Task {} is process-bound: {}\", taskId, e.getMessage()); }","preventionTips":["Query only standalone tasks with .processInstanceIdUnspecified() before deleting","Never bulk-delete tasks without filtering executionId/scopeType","Prefer ending/canceling the process instead of deleting its tasks"],"tags":["flowable","task","lifecycle","invalid-state-transition"],"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"}