flowable/flowable-engine · error · FlowableIllegalArgumentException

Provided channel definition must have a deployment id.

Error message

Provided channel definition must have a deployment id.

What it means

getPersistedInstanceOfChannelDefinition throws FlowableIllegalArgumentException when the given ChannelDefinitionEntity has a null/empty deploymentId. The method fetches the persisted (database) version of a deployed channel definition, which requires a deployment id to locate it.

Source

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

        ChannelDefinitionEntity existingDefinition = null;

        if (tenantId != null && !tenantId.equals(EventRegistryEngineConfiguration.NO_TENANT_ID)) {
            existingDefinition = channelDefinitionEntityManager.findLatestChannelDefinitionByKeyAndTenantId(key, tenantId);
        } else {
            existingDefinition = channelDefinitionEntityManager.findLatestChannelDefinitionByKey(key);
        }

        return existingDefinition;
    }

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

        ChannelDefinitionEntityManager channelDefinitionEntityManager = CommandContextUtil.getEventRegistryConfiguration().getChannelDefinitionEntityManager();

        ChannelDefinitionEntity persistedChannelDefinition = null;
        if (channelDefinition.getTenantId() == null || EventRegistryEngineConfiguration.NO_TENANT_ID.equals(channelDefinition.getTenantId())) {
            persistedChannelDefinition = channelDefinitionEntityManager.findChannelDefinitionByDeploymentAndKey(deploymentId, channelDefinition.getKey());
        } else {
            persistedChannelDefinition = channelDefinitionEntityManager.findChannelDefinitionByDeploymentAndKeyAndTenantId(deploymentId,
                            channelDefinition.getKey(), channelDefinition.getTenantId());
        }

        return persistedChannelDefinition;
    }
}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Ensure channelDefinition.setDeploymentId(...) is called before invoking this method (normally done by the deployer during updateCachingAndArtifacts).
  2. Only call this helper with definitions that have already gone through deployment persistence.
  3. If constructing definitions in tests, set a deploymentId of an actually deployed deployment.

Example fix

// before
ChannelDefinitionEntity def = channelDefinitionEntityManager.create();
helper.getPersistedInstanceOfChannelDefinition(def); // no deploymentId
// after
def.setDeploymentId(deployment.getId());
helper.getPersistedInstanceOfChannelDefinition(def);
Defensive patterns

Strategy: validation

Validate before calling

if (channelDefinition.getDeploymentId() == null || channelDefinition.getDeploymentId().isEmpty()) throw new IllegalArgumentException("channelDefinition.deploymentId required before persistence lookup");

Try / catch

try { helper.getPersistedInstanceOfChannelDefinition(def); } catch (FlowableIllegalArgumentException e) { log.error("Definition not deployed: {}", e.getMessage()); }

Prevention

When it happens

Trigger: Calling getPersistedInstanceOfChannelDefinition with a channel definition that was never persisted/deployed, or one whose deploymentId field was not set during the deployment pipeline (e.g. built in memory for tests or a partially initialized entity).

Common situations: Custom deployment code that builds ChannelDefinitionEntity objects manually without setting deploymentId, calling the helper before ChannelDefinitionDeploymentHelper has assigned the deployment, or copying entities between sessions losing the id.

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/9bc293d7ccb2bd75. Report an issue: GitHub.