{"record":{"id":"2bccf50b3d2d9470","repo":"flowable/flowable-engine","slug":"the-process-definition-id-is-mandatory-but-pro","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":"warning","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetDeploymentProcessDiagramCmd.java","lineNumber":41,"sourceCode":"import org.flowable.engine.repository.ProcessDefinition;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * Gives access to a deployed process diagram, e.g., a PNG image, through a stream of bytes.\n * \n * @author Falko Menge\n */\npublic class GetDeploymentProcessDiagramCmd implements Command<InputStream>, Serializable {\n\n    private static final long serialVersionUID = 1L;\n    private static final Logger LOGGER = LoggerFactory.getLogger(GetDeploymentProcessDiagramCmd.class);\n\n    protected String processDefinitionId;\n\n    public GetDeploymentProcessDiagramCmd(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 InputStream execute(CommandContext commandContext) {\n        ProcessDefinition processDefinition = CommandContextUtil.getProcessEngineConfiguration(commandContext).getDeploymentManager().findDeployedProcessDefinitionById(processDefinitionId);\n        String deploymentId = processDefinition.getDeploymentId();\n        String resourceName = processDefinition.getDiagramResourceName();\n        if (resourceName == null) {\n            LOGGER.info(\"Resource name is null! No process diagram stream exists.\");\n            return null;\n        } else {\n            InputStream processDiagramStream = new GetDeploymentResourceCmd(deploymentId, resourceName).execute(commandContext);\n            return processDiagramStream;\n        }\n    }\n","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/GetDeploymentProcessDiagramCmd.java#L23-L59","documentation":"FlowableIllegalArgumentException thrown by the GetDeploymentProcessDiagramCmd constructor when processDefinitionId is null or an empty string. The command needs a non-empty id to look up the process definition resource, so it fails fast on construction. This is a caller-side input validation error.","triggerScenarios":"Calling repositoryService.getProcessDiagram(null) or getProcessDiagram(\"\") — typically the id came from an uninitialized variable, an unmarshal/parse step, or ProcessInstance.getProcessDefinitionId() returning null on an incomplete entity.","commonSituations":"Building a REST endpoint that passes a request path segment straight through without validation; fetching the diagram before a process definition variable was populated; copy-paste using processInstanceId instead of processDefinitionId.","solutions":["Validate the id before constructing the command: non-null, non-empty, expected format (e.g. myProcess:1:1234).","Resolve the id from a reliable source: ProcessDefinitionQuery().processDefinitionKey(key).latestVersion().singleResult().getId().","Catch FlowableIllegalArgumentException in the calling layer and return a 400-style validation error.","Fix callers that pass processInstanceId where processDefinitionId is expected."],"exampleFix":"// before\nrepositoryService.getProcessDiagram(request.getId()); // may be null/empty\n// after\nif (id == null || id.isEmpty()) {\n    throw new IllegalArgumentException(\"processDefinitionId required\");\n}\nrepositoryService.getProcessDiagram(id);","handlingStrategy":"validation","validationCode":"if (id == null || id.trim().isEmpty())\n    throw new IllegalArgumentException(\"processDefinitionId is mandatory\");","typeGuard":"Optional<ProcessDefinition> requireDefinition(String id) {\n    return Optional.ofNullable(id)\n        .filter(s -> !s.isBlank())\n        .map(sid -> repositoryService.createProcessDefinitionQuery()\n            .processDefinitionId(sid).singleResult());\n}","tryCatchPattern":"try {\n    return repositoryService.getProcessDiagram(id);\n} catch (FlowableIllegalArgumentException e) {\n    throw new BadRequestException(\"A non-empty processDefinitionId is required\", e);\n}","preventionTips":["Validate ids at the API boundary before they reach engine commands.","Never pass processInstanceId where a processDefinitionId is expected.","Use Optional or explicit null checks when ids come from lookups.","Unit-test diagram helpers with null/empty ids to lock in behavior."],"tags":["flowable","validation","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"}