{"record":{"id":"bdf93c612473188f","repo":"flowable/flowable-engine","slug":"empty-taskid-is-not-allowed-for-historictasklogent","errorCode":null,"errorMessage":"Empty taskId is not allowed for HistoricTaskLogEntry","messagePattern":"Empty taskId is not allowed for HistoricTaskLogEntry","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-task-service/src/main/java/org/flowable/task/service/impl/HistoricTaskLogEntryBuilderImpl.java","lineNumber":51,"sourceCode":"        super(task);\n        this.commandExecutor = commandExecutor;\n        this.taskServiceConfiguration = taskServiceConfiguration;\n    }\n\n    public HistoricTaskLogEntryBuilderImpl(CommandExecutor commandExecutor, TaskServiceConfiguration taskServiceConfiguration) {\n        this.commandExecutor = commandExecutor;\n        this.taskServiceConfiguration = taskServiceConfiguration;\n    }\n\n    @Override\n    public void create() {\n        this.commandExecutor.execute(this);\n    }\n\n    @Override\n    public Void execute(CommandContext commandContext) {\n        if (StringUtils.isEmpty(getTaskId())) {\n            throw new FlowableIllegalArgumentException(\"Empty taskId is not allowed for HistoricTaskLogEntry\");\n        }\n        if (StringUtils.isEmpty(getUserId())) {\n            userId(Authentication.getAuthenticatedUserId());\n        }\n        if (timeStamp == null) {\n            timeStamp(taskServiceConfiguration.getClock().getCurrentTime());\n        }\n\n        taskServiceConfiguration.getInternalHistoryTaskManager().recordHistoryUserTaskLog(this);\n        return null;\n    }\n\n}\n","sourceCodeStart":33,"sourceCodeEnd":65,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-task-service/src/main/java/org/flowable/task/service/impl/HistoricTaskLogEntryBuilderImpl.java#L33-L65","documentation":"Flowable throws this FlowableIllegalArgumentException when a HistoricTaskLogEntryBuilderImpl command is executed with an empty or null taskId. A task-log entry must reference a specific task, so the builder refuses to persist an entry without one. The check runs in execute() inside the command, i.e. when the log entry is actually written.","triggerScenarios":"Calling taskService... on a HistoricTaskLogEntryBuilder (e.g. addLogType(...) followed by execute/trigger) without setting taskId, or setting taskId to null/empty string.","commonSituations":"Logging helper code that records task events where the task id was not yet assigned (e.g. before task creation); passing a variable holding the task id that is null because the task lookup failed.","solutions":["Set the taskId on the builder via .taskId(taskId) before executing the command.","Verify the task id is non-empty with StringUtils.isNotEmpty before building the log entry.","If the log is not task-scoped, use the correct builder/API for non-task log entries.","Ensure the task actually exists and its id was propagated to the logging code."],"exampleFix":"// before\nTaskLogEntryBuilder b = ...; b.type(\"start\").execute(); // empty taskId -> throws\n// after\nif (StringUtils.isNotEmpty(taskId)) {\n    taskService.createTaskLogEntryBuilder().taskId(taskId).type(\"start\").save();\n}","handlingStrategy":"validation","validationCode":"if (taskId == null || taskId.isEmpty()) {\n    throw new IllegalArgumentException(\"taskId required for task log entry\");\n}\ntaskService.createTaskLogEntryBuilder().taskId(taskId)...;","typeGuard":"boolean hasTaskId(String id) { return id != null && !id.isEmpty(); }","tryCatchPattern":"try {\n    builder.execute();\n} catch (FlowableIllegalArgumentException e) {\n    if (e.getMessage().contains(\"Empty taskId is not allowed\")) {\n        log.error(\"Attempted to write task log entry without taskId\");\n    } else { throw e; }\n}","preventionTips":["Only create task log entries after the task id is known/persisted","Wrap log-entry creation in a helper that asserts a non-empty task id","Verify task lookup succeeded before logging events for it","Skip (or defer) logging when the task id is unavailable instead of failing"],"tags":["flowable","task-log","null-argument","validation"],"backgroundTag":"empty-required-field","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}