{"record":{"id":"176ee14c5f3a6e01","repo":"flowable/flowable-engine","slug":"taskid-is-null-176ee1","errorCode":null,"errorMessage":"taskId is null","messagePattern":"taskId is null","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/DeleteHistoricTaskInstanceCmd.java","lineNumber":43,"sourceCode":"import org.flowable.task.service.impl.persistence.entity.HistoricTaskInstanceEntity;\n\n/**\n * @author Tom Baeyens\n */\npublic class DeleteHistoricTaskInstanceCmd implements Command<Object>, Serializable {\n\n    private static final long serialVersionUID = 1L;\n    protected String taskId;\n\n    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}","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/DeleteHistoricTaskInstanceCmd.java#L25-L61","documentation":"DeleteHistoricTaskInstanceCmd validates that taskId is non-null before looking up the historic task. A null taskId is a caller-side contract violation and the engine throws FlowableIllegalArgumentException without touching the database.","triggerScenarios":"historyService.deleteHistoricTask(taskId) or related APIs executed with a null id, e.g. a task id variable never set, or a completed task listener forwarding a null id.","commonSituations":"Using task.getId() from an object that was never persisted, mapping errors in delegation code, or calling delete inside an event handler where the task reference is not yet available.","solutions":["Pass a valid non-null task id to the delete API","Capture Task.getId() when the task completes and store it for later deletion","Null-check the id before invoking the command"],"exampleFix":"// before\nhistoryService.deleteHistoricTask(taskId); // taskId null\n// after\nif (taskId != null) {\n    historyService.deleteHistoricTask(taskId);\n}","handlingStrategy":"validation","validationCode":"if (taskId == null || taskId.trim().isEmpty()) {\n    throw new IllegalArgumentException(\"taskId must be provided before deleting historic task\");\n}","typeGuard":"boolean hasTaskId = id -> id != null && !id.trim().isEmpty();","tryCatchPattern":"try {\n    historyService.deleteHistoricTask(taskId);\n} catch (FlowableIllegalArgumentException e) {\n    logger.warn(\"Null taskId passed to deleteHistoricTask\", e);\n}","preventionTips":["Capture Task.getId() at task creation/completion time","Null-check ids at API boundaries","Avoid passing entity objects' ids that may not yet be persisted"],"tags":["flowable","null-argument","history","task"],"backgroundTag":"null-argument","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"}