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

  1. Ensure the ProcessDefinitionEntity is associated with a deployment (setDeploymentId with a valid persisted deployment id) before calling this method
  2. Call this method only after the deployment itself has been persisted (after the deployment entity insert step)
  3. Check custom deployer/listener ordering — the code must run after CachingAndArtifactsManager has stored the deployment
  4. 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

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


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)