{"record":{"id":"8a45fc4282f334d8","repo":"flowable/flowable-engine","slug":"the-process-definition-id-is-mandatory-but-pro-8a45fc","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":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"warning","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetDeploymentProcessDiagramLayoutCmd.java","lineNumber":39,"sourceCode":"import org.flowable.common.engine.impl.interceptor.CommandContext;\nimport org.flowable.engine.impl.bpmn.diagram.ProcessDiagramLayoutFactory;\nimport org.flowable.engine.repository.DiagramLayout;\n\n/**\n * Provides positions and dimensions of elements in a process diagram as provided by {@link GetDeploymentProcessDiagramCmd}.\n * \n * This command requires a process model and a diagram image to be deployed.\n * \n * @author Falko Menge\n */\npublic class GetDeploymentProcessDiagramLayoutCmd implements Command<DiagramLayout>, Serializable {\n\n    private static final long serialVersionUID = 1L;\n    protected String processDefinitionId;\n\n    public GetDeploymentProcessDiagramLayoutCmd(String processDefinitionId) {\n        if (processDefinitionId == null || processDefinitionId.length() < 1) {\n            throw new FlowableException(\"The process definition id is mandatory, but '\" + processDefinitionId + \"' has been provided.\");\n        }\n        this.processDefinitionId = processDefinitionId;\n    }\n\n    @Override\n    public DiagramLayout execute(CommandContext commandContext) {\n        InputStream processModelStream = new GetDeploymentProcessModelCmd(processDefinitionId).execute(commandContext);\n        InputStream processDiagramStream = new GetDeploymentProcessDiagramCmd(processDefinitionId).execute(commandContext);\n        return new ProcessDiagramLayoutFactory().getProcessDiagramLayout(processModelStream, processDiagramStream);\n    }\n\n}\n","sourceCodeStart":21,"sourceCodeEnd":52,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetDeploymentProcessDiagramLayoutCmd.java#L21-L52","documentation":"FlowableException (notably the non-IllegalArgumentException variant here) thrown by the GetDeploymentProcessDiagramLayoutCmd constructor when processDefinitionId is null or empty. The layout command cannot fetch diagram coordinates without an id, so it validates immediately. Note this sibling command throws FlowableException where others throw FlowableIllegalArgumentException.","triggerScenarios":"Calling repositoryService.getProcessDiagramLayout(null) or with \"\" — e.g. id derived from a missing process definition reference or a wrong request parameter.","commonSituations":"UI code that fetches a diagram layout using an id that was never set; frameworks that call the API with default-empty strings; tests passing null to check behavior and unexpectedly getting FlowableException instead of IllegalArgumentException.","solutions":["Validate the id before the call (null/empty check) and fail with your own descriptive error.","Look up a valid id via RepositoryService.createProcessDefinitionQuery().latestVersion().","Catch FlowableException (this class throws the broader type) when handling the error.","Verify you are not passing processInstanceId or deploymentId by mistake."],"exampleFix":"// before\nDiagramLayout layout = repositoryService.getProcessDiagramLayout(pid);\n// after\nif (pid == null || pid.trim().isEmpty()) throw new IllegalArgumentException(\"id required\");\nDiagramLayout layout = repositoryService.getProcessDiagramLayout(pid);","handlingStrategy":"validation","validationCode":"if (id == null || id.trim().isEmpty())\n    throw new IllegalArgumentException(\"processDefinitionId is mandatory\");","typeGuard":"boolean hasDefinitionId(ProcessDefinition def) {\n    return def != null && def.getId() != null && !def.getId().isBlank();\n}","tryCatchPattern":"try {\n    return repositoryService.getProcessDiagramLayout(id);\n} catch (FlowableException e) {\n    // note: this command throws the broader FlowableException\n    throw new BadRequestException(\"A non-empty processDefinitionId is required\", e);\n}","preventionTips":["Check ids before calling; this variant throws FlowableException, so catch that base type.","Resolve latest-version ids with ProcessDefinitionQuery instead of manual input.","Sanitize request parameters (reject blank strings early).","Add contract tests covering null/empty id arguments."],"tags":["flowable","validation","argument","diagram-layout"],"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"}