{"record":{"id":"77444dd05c335d73","repo":"Activiti/Activiti","slug":"provided-process-definition-must-have-a-deployment","errorCode":null,"errorMessage":"Provided process definition must have a deployment id.","messagePattern":"Provided process definition must have a deployment id\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"activiti-core/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/deployer/BpmnDeploymentHelper.java","lineNumber":133,"sourceCode":"        if (tenantId != null && !tenantId.equals(ProcessEngineConfiguration.NO_TENANT_ID)) {\n            existingDefinition = processDefinitionManager.findLatestProcessDefinitionByKeyAndTenantId(key, tenantId);\n        } else {\n            existingDefinition = processDefinitionManager.findLatestProcessDefinitionByKey(key);\n        }\n\n        return existingDefinition;\n    }\n\n    /**\n     * Gets the persisted version of the already-deployed process definition.  Note that this is\n     * different from {@link #getMostRecentVersionOfProcessDefinition} as it looks specifically for\n     * a process definition that is already persisted and attached to a particular deployment,\n     * rather than the latest version across all deployments.\n     */\n    public ProcessDefinitionEntity getPersistedInstanceOfProcessDefinition(ProcessDefinitionEntity processDefinition) {\n        String deploymentId = processDefinition.getDeploymentId();\n        if (StringUtils.isEmpty(processDefinition.getDeploymentId())) {\n            throw new IllegalStateException(\"Provided process definition must have a deployment id.\");\n        }\n\n        ProcessDefinitionEntityManager processDefinitionManager = Context.getCommandContext()\n            .getProcessEngineConfiguration()\n            .getProcessDefinitionEntityManager();\n        ProcessDefinitionEntity persistedProcessDefinition = null;\n        if (\n            processDefinition.getTenantId() == null ||\n            ProcessEngineConfiguration.NO_TENANT_ID.equals(processDefinition.getTenantId())\n        ) {\n            persistedProcessDefinition = processDefinitionManager.findProcessDefinitionByDeploymentAndKey(\n                deploymentId,\n                processDefinition.getKey()\n            );\n        } else {\n            persistedProcessDefinition = processDefinitionManager.findProcessDefinitionByDeploymentAndKeyAndTenantId(\n                deploymentId,\n                processDefinition.getKey(),","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/Activiti/Activiti/blob/56435b1a97deeafdc09dd40074b056c89fba5a8a/activiti-core/activiti-engine/src/main/java/org/activiti/engine/impl/bpmn/deployer/BpmnDeploymentHelper.java#L115-L151","documentation":"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.","triggerScenarios":"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.","commonSituations":"Custom DeploymentListeners or deployers that operate on parsed definitions before ParsedDeployment attaches them to a deployment; copy/clone code that drops the deploymentId field.","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"],"exampleFix":"// before\nhelper.getPersistedInstanceOfProcessDefinition(parsedDef.getProcessDefinition());\n// after\nif (StringUtils.isNotEmpty(parsedDef.getProcessDefinition().getDeploymentId())) {\n    helper.getPersistedInstanceOfProcessDefinition(parsedDef.getProcessDefinition());\n}","handlingStrategy":"type-guard","validationCode":"if (processDefinition.getDeploymentId() == null || processDefinition.getDeploymentId().isEmpty()) { throw new IllegalArgumentException(\"definition not yet persisted\"); }","typeGuard":"boolean isPersisted(ProcessDefinitionEntity d) { return d.getDeploymentId() != null && !d.getDeploymentId().isEmpty(); }","tryCatchPattern":null,"preventionTips":["Only query persisted instances after the deployment insert step","Never construct ProcessDefinitionEntity manually for redeploy flows"],"tags":["deployment","process-definition","illegal-state","activiti"],"backgroundTag":"missing-required-argument","analyzedSha":"56435b1a97deeafdc09dd40074b056c89fba5a8a","analyzedAt":"2026-09-09T21:00:06.703Z","contentChangedAt":"2026-09-09T21:00:06.703Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}