{"record":{"id":"f422dbb89a5132d5","repo":"flowable/flowable-engine","slug":"the-process-definition-id-is-mandatory-but-has","errorCode":null,"errorMessage":"The process definition id is mandatory, but '' has been provided.","messagePattern":"The process definition id 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":53,"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 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;\n        if (taskDefinitionKey == null) {\n            // TODO: Maybe add getFormKey() to FormHandler interface to avoid the following cast\n            formHandler = (DefaultFormHandler) processDefinition.getStartFormHandler();\n        } else {\n            TaskDefinition taskDefinition = processDefinition.getTaskDefinitions().get(taskDefinitionKey);\n            // TODO: Maybe add getFormKey() to FormHandler interface to avoid the following cast\n            formHandler = (DefaultFormHandler) taskDefinition.getTaskFormHandler();","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/GetFormKeyCmd.java#L35-L71","documentation":"GetFormKeyCmd requires a non-empty processDefinitionId to look up a form key. The setter setProcessDefinitionId throws ActivitiIllegalArgumentException when the id is null or an empty string, failing fast instead of issuing a doomed database lookup.","triggerScenarios":"Calling FormService.getFormKey(null) or getFormKey(\"\") for a process definition; callers often pass an empty id from unparsed request parameters or blank config values.","commonSituations":"REST/API layer receiving an empty path variable; a process definition id variable that was never populated; typos where the deployment key is passed instead of the definition id.","solutions":["Pass a valid non-empty process definition id obtained from RepositoryService.createProcessDefinitionQuery() results","Validate/trim the id in your caller code before invoking getFormKey","If you only have a key, resolve the latest definition id via processDefinitionQuery().processDefinitionKey(key).latestVersion().singleResult()"],"exampleFix":"// before\nString formKey = formService.getFormKey(\"\");\n// after\nProcessDefinition pd = repositoryService.createProcessDefinitionQuery()\n    .processDefinitionKey(\"myProcess\").latestVersion().singleResult();\nString formKey = pd != null ? formService.getFormKey(pd.getId()) : null;","handlingStrategy":"validation","validationCode":"if (processDefinitionId == null || processDefinitionId.trim().isEmpty()) {\n    throw new IllegalArgumentException(\"processDefinitionId must be a non-empty string\");\n}","typeGuard":"boolean isValidDefinitionId(String id) { return id != null && !id.trim().isEmpty(); }","tryCatchPattern":"try {\n    formService.getFormKey(definitionId);\n} catch (ActivitiIllegalArgumentException e) {\n    // treat as bad request: missing/empty definition id\n}","preventionTips":["Resolve ids via ProcessDefinitionQuery rather than hand-built strings","Trim and check emptiness of ids parsed from requests","Log the id at debug level before engine calls to spot empty values early"],"tags":["flowable","activiti","illegal-argument","process-definition"],"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"}