Activiti/Activiti · error · IllegalStateException
Provided process definition must have a deployment id.
Error message
Provided process definition must have a deployment id.
What it means
getPersistedInstanceOfProcessDefinition needs a deploymentId to fetch the exact persisted row of a process definition; without one it cannot disambiguate which deployment's version is meant. It throws IllegalStateException when the passed entity's deploymentId is empty/null. This is an internal-invariant check on the entity, typically during redeployment/timer-driven redeploy flows.
Solutions
- Ensure the ProcessDefinitionEntity is associated with a deployment (setDeploymentId with a valid persisted deployment id) before calling this method
- Call this method only after the deployment itself has been persisted (after the deployment entity insert step)
- Check custom deployer/listener ordering — the code must run after CachingAndArtifactsManager has stored the deployment
- Debug why deploymentId is empty: inspect the entity right before the call
Example fix
// before
helper.getPersistedInstanceOfProcessDefinition(parsedDef.getProcessDefinition());
// after
if (StringUtils.isNotEmpty(parsedDef.getProcessDefinition().getDeploymentId())) {
helper.getPersistedInstanceOfProcessDefinition(parsedDef.getProcessDefinition());
} Defensive patterns
Strategy: type-guard
Validate before calling
if (processDefinition.getDeploymentId() == null || processDefinition.getDeploymentId().isEmpty()) { throw new IllegalArgumentException("definition not yet persisted"); } Type guard
boolean isPersisted(ProcessDefinitionEntity d) { return d.getDeploymentId() != null && !d.getDeploymentId().isEmpty(); } Prevention
- Only query persisted instances after the deployment insert step
- Never construct ProcessDefinitionEntity manually for redeploy flows
When it happens
Trigger: Invoking getPersistedInstanceOfProcessDefinition with a ProcessDefinitionEntity whose deploymentId property was never set — e.g. a freshly parsed (in-memory) definition passed through redeployment or custom deployer code before persistence.
Common situations: Custom DeploymentListeners or deployers that operate on parsed definitions before ParsedDeployment attaches them to a deployment; copy/clone code that drops the deploymentId field.
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
- Cannot start process instance. Process model (id =
- No process definition found for id =
- Provided process definition must have its resource name set.
- Cannot deploy process definition
- Cannot execute operation because process definition
AI-assisted analysis of Activiti/Activiti@56435b1a97 (2026-09-09).
Data as JSON: /api/errors/77444dd05c335d73.
Report an issue: GitHub.
Appendix: source
Thrown at activiti-core/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/deployer/BpmnDeploymentHelper.java:133
if (tenantId != null && !tenantId.equals(ProcessEngineConfiguration.NO_TENANT_ID)) {
existingDefinition = processDefinitionManager.findLatestProcessDefinitionByKeyAndTenantId(key, tenantId);
} else {
existingDefinition = processDefinitionManager.findLatestProcessDefinitionByKey(key);
}
return existingDefinition;
}
/**
* Gets the persisted version of the already-deployed process definition. Note that this is
* different from {@link #getMostRecentVersionOfProcessDefinition} as it looks specifically for
* a process definition that is already persisted and attached to a particular deployment,
* rather than the latest version across all deployments.
*/
public ProcessDefinitionEntity getPersistedInstanceOfProcessDefinition(ProcessDefinitionEntity processDefinition) {
String deploymentId = processDefinition.getDeploymentId();
if (StringUtils.isEmpty(processDefinition.getDeploymentId())) {
throw new IllegalStateException("Provided process definition must have a deployment id.");
}
ProcessDefinitionEntityManager processDefinitionManager = Context.getCommandContext()
.getProcessEngineConfiguration()
.getProcessDefinitionEntityManager();
ProcessDefinitionEntity persistedProcessDefinition = null;
if (
processDefinition.getTenantId() == null ||
ProcessEngineConfiguration.NO_TENANT_ID.equals(processDefinition.getTenantId())
) {
persistedProcessDefinition = processDefinitionManager.findProcessDefinitionByDeploymentAndKey(
deploymentId,
processDefinition.getKey()
);
} else {
persistedProcessDefinition = processDefinitionManager.findProcessDefinitionByDeploymentAndKeyAndTenantId(
deploymentId,
processDefinition.getKey(),View on GitHub (pinned to 56435b1a97)