{"record":{"id":"4e817ecd2f914336","repo":"flowable/flowable-engine","slug":"the-task-definition-key-is-mandatory-but-taskd","errorCode":null,"errorMessage":"The task definition key is mandatory, but '${taskDefinitionKey}' has been provided.","messagePattern":"The task definition key is mandatory, but '(.+?)' has been provided\\.","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetFormKeyCmd.java","lineNumber":49,"sourceCode":"public class GetFormKeyCmd implements Command<String> {\n\n    protected String taskDefinitionKey;\n    protected String processDefinitionId;\n\n    /**\n     * Retrieves a start form key.\n     */\n    public GetFormKeyCmd(String processDefinitionId) {\n        setProcessDefinitionId(processDefinitionId);\n    }\n\n    /**\n     * Retrieves a task form key.\n     */\n    public GetFormKeyCmd(String processDefinitionId, String taskDefinitionKey) {\n        setProcessDefinitionId(processDefinitionId);\n        if (taskDefinitionKey == null || taskDefinitionKey.length() < 1) {\n            throw new FlowableIllegalArgumentException(\"The task definition key is mandatory, but '\" + taskDefinitionKey + \"' has been provided.\");\n        }\n        this.taskDefinitionKey = taskDefinitionKey;\n    }\n\n    protected void setProcessDefinitionId(String processDefinitionId) {\n        if (processDefinitionId == null || processDefinitionId.length() < 1) {\n            throw new FlowableIllegalArgumentException(\"The process definition id is mandatory, but '\" + processDefinitionId + \"' has been provided.\");\n        }\n        this.processDefinitionId = processDefinitionId;\n    }\n\n    @Override\n    public String execute(CommandContext commandContext) {\n        ProcessDefinition processDefinition = ProcessDefinitionUtil.getProcessDefinition(processDefinitionId);\n\n        if (Flowable5Util.isFlowable5ProcessDefinition(processDefinition, commandContext)) {\n            return Flowable5Util.getFlowable5CompatibilityHandler().getFormKey(processDefinitionId, taskDefinitionKey);\n        }","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetFormKeyCmd.java#L31-L67","documentation":"The GetFormKeyCmd constructor validates its taskDefinitionKey argument and throws FlowableIllegalArgumentException when it is null or an empty string. The task definition key identifies which user task inside the process the form key belongs to, so it is mandatory for the lookup.","triggerScenarios":"new GetFormKeyCmd(processDefinitionId, null) or new GetFormKeyCmd(processDefinitionId, \"\") — typically when the taskDefinitionKey is taken from a runtime task whose formKey/definitionKey was never set, or a variable holding the key resolved to empty.","commonSituations":"Fetching form keys for tasks created outside normal task definitions; passing TaskInfo.taskDefinitionKey when the task is a standalone task with no definition; string-trimming a key down to nothing.","solutions":["Supply a non-empty taskDefinitionKey obtained from the runtime task (task.getTaskDefinitionKey()).","Guard the call: skip form-key resolution when the key is null/empty, since standalone tasks have no form key.","If the key is empty because the task was created via TaskService.newTask(), do not attempt form-key lookup for such tasks."],"exampleFix":"// before\nString formKey = taskService.getTaskFormKey(processDefinitionId, task.getTaskDefinitionKey());\n// after\nString key = task.getTaskDefinitionKey();\nString formKey = (key != null && !key.isEmpty())\n    ? taskService.getTaskFormKey(processDefinitionId, key)\n    : null;","handlingStrategy":"validation","validationCode":"if (taskDefinitionKey == null || taskDefinitionKey.isEmpty()) {\n    return null; // standalone tasks have no form key\n}","typeGuard":"boolean hasKey(String s) { return s != null && !s.isEmpty(); }","tryCatchPattern":"try {\n    return taskService.getTaskFormKey(processDefinitionId, taskDefinitionKey);\n} catch (FlowableIllegalArgumentException e) {\n    return null;\n}","preventionTips":["Read the key from task.getTaskDefinitionKey() only for process-owned tasks","Skip form-key resolution for standalone TaskService tasks","Never trim keys to empty before passing them"],"tags":["flowable","argument-validation","empty-string","form-key"],"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-14T11:17:12.474Z"}