flowable/flowable-engine · error · FlowableIllegalArgumentException

Provided event definition must have a deployment id.

Error message

Provided event definition must have a deployment id.

What it means

getPersistedInstanceOfEventDefinition resolves the database-persisted version of an already-deployed event definition, which requires the in-memory entity to know which deployment it came from. If the entity's deploymentId is empty, the lookup cannot proceed and Flowable throws this FlowableIllegalArgumentException.

Source

Thrown at modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/deployer/EventDefinitionDeploymentHelper.java:106

        EventDefinitionEntity existingDefinition = null;

        if (tenantId != null && !tenantId.equals(EventRegistryEngineConfiguration.NO_TENANT_ID)) {
            existingDefinition = eventDefinitionEntityManager.findLatestEventDefinitionByKeyAndTenantId(key, tenantId);
        } else {
            existingDefinition = eventDefinitionEntityManager.findLatestEventDefinitionByKey(key);
        }

        return existingDefinition;
    }

    /**
     * Gets the persisted version of the already-deployed event definition.
     */
    public EventDefinitionEntity getPersistedInstanceOfEventDefinition(EventDefinitionEntity eventDefinition) {
        String deploymentId = eventDefinition.getDeploymentId();
        if (StringUtils.isEmpty(eventDefinition.getDeploymentId())) {
            throw new FlowableIllegalArgumentException("Provided event definition must have a deployment id.");
        }

        EventDefinitionEntityManager eventDefinitionEntityManager = CommandContextUtil.getEventRegistryConfiguration().getEventDefinitionEntityManager();

        EventDefinitionEntity persistedEventDefinition = null;
        if (eventDefinition.getTenantId() == null || EventRegistryEngineConfiguration.NO_TENANT_ID.equals(eventDefinition.getTenantId())) {
            persistedEventDefinition = eventDefinitionEntityManager.findEventDefinitionByDeploymentAndKey(deploymentId, eventDefinition.getKey());
        } else {
            persistedEventDefinition = eventDefinitionEntityManager.findEventDefinitionByDeploymentAndKeyAndTenantId(deploymentId,
                            eventDefinition.getKey(), eventDefinition.getTenantId());
        }

        return persistedEventDefinition;
    }
}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Ensure the entity's deploymentId is set before calling (usually by letting the normal deployment pipeline persist it first)
  2. Look up the persisted definition via EventDefinitionEntityManager by key/tenant instead of calling this helper with an unpersisted entity
  3. If you construct entities yourself, call setDeploymentId with the id of the deployment that contains the definition

Example fix

// before
EventDefinitionEntity entity = parseMyEventDefinition();
EventDefinitionEntity persisted = helper.getPersistedInstanceOfEventDefinition(entity);
// after
EventDefinitionEntity entity = parseMyEventDefinition();
entity.setDeploymentId(deployment.getId());
EventDefinitionEntity persisted = helper.getPersistedInstanceOfEventDefinition(entity);
Defensive patterns

Strategy: type-guard

Validate before calling

if (eventDefinition == null || eventDefinition.getDeploymentId() == null || eventDefinition.getDeploymentId().isEmpty()) {
    throw new IllegalStateException("Event definition must be deployed (deploymentId set) first");
}

Type guard

boolean isDeployed(EventDefinitionEntity def) {
    return def != null && def.getDeploymentId() != null && !def.getDeploymentId().isEmpty();
}

Try / catch

try {
    return helper.getPersistedInstanceOfEventDefinition(entity);
} catch (FlowableIllegalArgumentException e) {
    if (e.getMessage().contains("deployment id")) { /* deploy/lookup by key instead */ }
    throw e;
}

Prevention

When it happens

Trigger: Calling getPersistedInstanceOfEventDefinition with an EventDefinitionEntity that has not been through deployment (deploymentId never set), e.g. a freshly parsed or manually constructed entity.

Common situations: Custom deployer or migration code that builds EventDefinitionEntity objects manually and passes them to the helper before persisting; calling the helper from a custom Command outside the normal deployment pipeline.

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 flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/1fd744f2979803fa. Report an issue: GitHub.