flowable/flowable-engine · error · ActivitiException
The process definition id is mandatory, but
Error message
The process definition id is mandatory, but '${processDefinitionId}' has been provided. What it means
GetDeploymentProcessDiagramLayoutCmd's constructor validates the process definition id and throws ActivitiException when it is null or an empty string. The diagram-layout lookup command cannot proceed without a concrete process definition id, so it fails fast at command construction instead of during execution. This is a guard against passing an unset/blank id into the engine's command stack.
Solutions
- Pass a valid, non-empty process definition id obtained from repositoryService.createProcessDefinitionQuery() or ProcessInstance.getProcessDefinitionId().
- Check your own code for the variable that yields null/empty before calling the API; fix the upstream lookup.
- Confirm you are not accidentally passing a deploymentId or processInstanceId where a processDefinitionId is required.
Example fix
// before
DiagramLayout layout = repositoryService.getProcessDiagramLayout(processDefinitionId); // throws when null/empty
// after
if (processDefinitionId == null || processDefinitionId.isEmpty()) {
processDefinitionId = runtimeService.createProcessInstanceQuery()
.processInstanceId(processInstanceId).singleResult().getProcessDefinitionId();
}
DiagramLayout layout = repositoryService.getProcessDiagramLayout(processDefinitionId); Defensive patterns
Strategy: validation
Validate before calling
if (processDefinitionId == null || processDefinitionId.trim().isEmpty()) {
throw new IllegalArgumentException("processDefinitionId must be a non-empty string");
} Type guard
boolean isValidProcessDefinitionId(String id) { return id != null && !id.trim().isEmpty(); } Try / catch
try {
DiagramLayout layout = repositoryService.getProcessDiagramLayout(processDefinitionId);
} catch (ActivitiException e) {
if (e.getMessage() != null && e.getMessage().contains("mandatory")) {
throw new IllegalStateException("processDefinitionId was not resolved before diagram lookup", e);
}
throw e;
} Prevention
- Always source the id from a ProcessDefinition/ProcessInstance object, never from hand-built strings.
- Validate ids at service-layer boundaries before touching the engine API.
When it happens
Trigger: Calling runtimeService/managementService APIs that build GetDeploymentProcessDiagramLayoutCmd (e.g. repositoryService.getProcessDiagramLayout(processDefinitionId)) with a null or "" processDefinitionId.
Common situations: Developers pass a variable that was never populated because a prior deployment/process-start call returned null or the wrong field was read (e.g. using deployment id or process instance id instead of process definition id); also common after refactoring where a definition-id lookup result was not null-checked.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- process definition id is null
- process definition id is null
- Process definition id or key cannot be null
- processDefinitionId is null
- processDefinitionId is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/8e68ee0b381c7e50.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/cmd/GetDeploymentProcessDiagramLayoutCmd.java:39
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.repository.DiagramLayout;
/**
* Provides positions and dimensions of elements in a process diagram as provided by {@link GetDeploymentProcessDiagramCmd}.
*
* This command requires a process model and a diagram image to be deployed.
*
* @author Falko Menge
*/
public class GetDeploymentProcessDiagramLayoutCmd implements Command<DiagramLayout>, Serializable {
private static final long serialVersionUID = 1L;
protected String processDefinitionId;
public GetDeploymentProcessDiagramLayoutCmd(String processDefinitionId) {
if (processDefinitionId == null || processDefinitionId.length() < 1) {
throw new ActivitiException("The process definition id is mandatory, but '" + processDefinitionId + "' has been provided.");
}
this.processDefinitionId = processDefinitionId;
}
@Override
public DiagramLayout execute(CommandContext commandContext) {
InputStream processModelStream = new GetDeploymentProcessModelCmd(processDefinitionId)
.execute(commandContext);
InputStream processDiagramStream = new GetDeploymentProcessDiagramCmd(processDefinitionId)
.execute(commandContext);
return new ProcessDiagramLayoutFactory().getProcessDiagramLayout(processModelStream, processDiagramStream);
}
}
View on GitHub (pinned to d6d39ce1c6)