{"record":{"id":"7ac1647a080cd37c","repo":"flowable/flowable-engine","slug":"the-task-definition-key-is-mandatory-but-has-b","errorCode":null,"errorMessage":"The task definition key is mandatory, but '' has been provided.","messagePattern":"The task definition key is mandatory, but '' has been provided\\.","errorType":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/GetFormKeyCmd.java","lineNumber":46,"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 ActivitiIllegalArgumentException(\"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 ActivitiIllegalArgumentException(\"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        ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) commandContext\n                .getProcessEngineConfiguration()\n                .getDeploymentManager()\n                .findDeployedProcessDefinitionById(processDefinitionId);\n        DefaultFormHandler formHandler;","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/GetFormKeyCmd.java#L28-L64","documentation":"The GetFormKeyCmd constructor validates its arguments at construction time: taskDefinitionKey must be a non-null, non-empty string, otherwise ActivitiIllegalArgumentException is thrown immediately (before the command is ever executed). The form key is looked up per task definition, so an empty key has no meaning.","triggerScenarios":"new GetFormKeyCmd(processDefinitionId, \"\") or (processDefinitionId, null); calling FormService.getFormKey(processDefinitionId, taskDefinitionKey) where the task definition key argument is empty, e.g. taken from a StartFormData/task object that lacks a key.","commonSituations":"Retrieving the form key for a start event using the wrong overload or an empty task definition key, template/property placeholders that resolved to empty strings, or data from a task whose definition key was never set.","solutions":["Pass the actual task definition key (task.getTaskDefinitionKey()); for start forms pass null/omit the taskDefinitionKey argument of the service method rather than an empty string.","Trim and validate the key before constructing the command; strip placeholder syntax like ${...} that may resolve empty.","Check the BPMN model: the userTask element must have a flowable:formKey or an id you intend to use as the definition key."],"exampleFix":"// before\nString key = task.getTaskDefinitionKey();\nString formKey = formService.getFormKey(processDefinitionId, key); // key may be \"\"\n// after\nString key = task.getTaskDefinitionKey();\nif (key == null || key.trim().isEmpty()) {\n    throw new IllegalArgumentException(\"task definition key is required to resolve the form key\");\n}\nString formKey = formService.getFormKey(processDefinitionId, key.trim());","handlingStrategy":"validation","validationCode":"if (taskDefinitionKey == null || taskDefinitionKey.trim().isEmpty()) {\n    throw new IllegalArgumentException(\"A non-empty task definition key is required to fetch the form key\");\n}","typeGuard":"boolean hasTaskDefinitionKey(String key) { return key != null && !key.trim().isEmpty(); }","tryCatchPattern":"try {\n    return formService.getFormKey(processDefinitionId, taskDefinitionKey);\n} catch (ActivitiIllegalArgumentException e) {\n    if (e.getMessage().contains(\"task definition key is mandatory\")) { log.warn(\"Empty task definition key\"); return null; }\n    throw e;\n}","preventionTips":["Use task.getTaskDefinitionKey() rather than hand-built strings.","For start forms, use the getFormKey(processDefinitionId) overload instead of passing an empty key.","Check BPMN userTask definitions for a real id/formKey before querying."],"tags":["invalid-argument-value","form","workflow-engine"],"backgroundTag":"missing-required-argument","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"}