{"record":{"id":"984a3a02ac872029","repo":"flowable/flowable-engine","slug":"task-does-not-have-an-endtime-cannot-delete-984a3a","errorCode":null,"errorMessage":"task does not have an endTime, cannot delete ","messagePattern":"task does not have an endTime, cannot delete ","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/DeleteHistoricTaskInstanceCmd.java","lineNumber":53,"sourceCode":"    public DeleteHistoricTaskInstanceCmd(String taskId) {\n        this.taskId = taskId;\n    }\n\n    @Override\n    public Object execute(CommandContext commandContext) {\n\n        if (taskId == null) {\n            throw new FlowableIllegalArgumentException(\"taskId is null\");\n        }\n\n        // Check if task is completed\n        HistoricTaskInstanceEntity historicTaskInstance = CommandContextUtil.getHistoricTaskService().getHistoricTask(taskId);\n\n        if (historicTaskInstance == null) {\n            throw new FlowableObjectNotFoundException(\"No historic task instance found with id: \" + taskId, HistoricTaskInstance.class);\n        }\n        if (historicTaskInstance.getEndTime() == null) {\n            throw new FlowableException(\"task does not have an endTime, cannot delete \" + historicTaskInstance);\n        }\n\n        CommandContextUtil.getHistoryManager(commandContext).recordHistoricTaskDeleted(historicTaskInstance);\n        \n        return null;\n    }\n\n}\n","sourceCodeStart":35,"sourceCodeEnd":62,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/DeleteHistoricTaskInstanceCmd.java#L35-L62","documentation":"DeleteHistoricTaskInstanceCmd requires the historic task to be finished: if getEndTime() is null the task is still open and the engine throws FlowableException. History deletion is reserved for completed tasks.","triggerScenarios":"historyService.deleteHistoricTask(taskId) on an active/uncompleted task, or on a task whose history row exists but has not received an endTime (still claimed/in-progress).","commonSituations":"Cleanup jobs that skip the completion check, deleting a task's history while its process is still running, or confusion between taskService (runtime) and historyService (history) deletion APIs.","solutions":["Complete the task first (taskService.complete(taskId)) before deleting its history","Check historicTaskInstance.getEndTime() != null before deleting","Use taskService-based deletion for active tasks instead of history APIs"],"exampleFix":"// before\nhistoryService.deleteHistoricTask(taskId); // task not finished\n// after\nHistoricTaskInstance hti = historyService.createHistoricTaskInstanceQuery()\n    .taskId(taskId).singleResult();\nif (hti != null && hti.getEndTime() != null) {\n    historyService.deleteHistoricTask(taskId);\n}","handlingStrategy":"validation","validationCode":"HistoricTaskInstance hti = historyService.createHistoricTaskInstanceQuery()\n    .taskId(taskId).singleResult();\nif (hti != null && hti.getEndTime() == null) {\n    throw new IllegalStateException(\"Task \" + taskId + \" is not finished; complete it first\");\n}","typeGuard":"boolean isTaskFinished = id -> {\n    HistoricTaskInstance h = historyService.createHistoricTaskInstanceQuery()\n        .taskId(id).singleResult();\n    return h != null && h.getEndTime() != null;\n};","tryCatchPattern":"try {\n    historyService.deleteHistoricTask(taskId);\n} catch (FlowableException e) {\n    if (e.getMessage().contains(\"endTime\")) {\n        logger.warn(\"Cannot delete history of unfinished task \" + taskId);\n    }\n}","preventionTips":["Only delete historic tasks whose endTime is set","Complete or resolve active tasks before history cleanup","Filter bulk deletions with .finished() on the historic task query"],"tags":["flowable","invalid-state","history","task"],"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-14T11:17:12.474Z"}