{"record":{"id":"b3949ad4088d3c8a","repo":"flowable/flowable-engine","slug":"the-process-definition-id-is-mandatory-but-pro-b3949a","errorCode":null,"errorMessage":"The process definition id is mandatory, but '${processDefinitionId}' has been provided.","messagePattern":"The process definition id 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":56,"sourceCode":"     */\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        }\n\n        FormHandlerHelper formHandlerHelper = CommandContextUtil.getProcessEngineConfiguration(commandContext).getFormHandlerHelper();\n        DefaultFormHandler formHandler;\n        if (taskDefinitionKey == null) {\n            // TODO: Maybe add getFormKey() to FormHandler interface to avoid the following cast\n            formHandler = (DefaultFormHandler) formHandlerHelper.getStartFormHandler(commandContext, processDefinition);\n        } else {","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetFormKeyCmd.java#L38-L74","documentation":"setProcessDefinitionId in GetFormKeyCmd throws FlowableIllegalArgumentException when the processDefinitionId is null or empty. The constructor calls this setter, so passing a missing process definition id to new GetFormKeyCmd fails immediately with this message.","triggerScenarios":"new GetFormKeyCmd(null, taskDefinitionKey) or with \"\" — commonly when the process definition id is derived from a task's processDefinitionId property that is null for standalone tasks, or an empty variable/parameter at the call site.","commonSituations":"Resolving form keys for standalone tasks (created via TaskService without a process) where getProcessDefinitionId() returns null; wiring form-key resolution generically over both standalone and process tasks.","solutions":["Only construct GetFormKeyCmd for tasks that belong to a process (check task.getProcessDefinitionId() != null first).","Pass the id resolved via taskService/identity of the running task rather than a possibly-empty variable.","Handle standalone tasks by returning a null/absent form key instead of calling the command."],"exampleFix":"// before\nString formKey = taskService.getTaskFormKey(task.getProcessDefinitionId(), task.getTaskDefinitionKey());\n// after\nString formKey = task.getProcessDefinitionId() != null\n    ? taskService.getTaskFormKey(task.getProcessDefinitionId(), task.getTaskDefinitionKey())\n    : null;","handlingStrategy":"validation","validationCode":"if (processDefinitionId == null || processDefinitionId.isEmpty()) {\n    return null;\n}","typeGuard":"boolean hasProcessDefinitionId(TaskInfo t) { return t.getProcessDefinitionId() != null && !t.getProcessDefinitionId().isEmpty(); }","tryCatchPattern":"try {\n    return taskService.getTaskFormKey(processDefinitionId, taskDefinitionKey);\n} catch (FlowableIllegalArgumentException e) {\n    return null;\n}","preventionTips":["Check task.getProcessDefinitionId() != null before form-key lookups","Treat standalone tasks (no process) as having no form key","Validate ids in a shared helper before constructing command objects"],"tags":["flowable","argument-validation","process-definition","form-key"],"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-14T11:17:12.474Z"}