flowable/flowable-engine · error · FlowableIllegalArgumentException

deploymentId is null

Error message

deploymentId is null

What it means

SetDeploymentTenantIdCmd.execute() validates that deploymentId is non-null and throws FlowableIllegalArgumentException if it is. Assigning a tenant id to an event deployment requires an existing deployment id.

Solutions

  1. Obtain the deployment id from the EventDeploymentEntity returned by the deploy call or a deployment query before setting the tenant.
  2. Validate deploymentId != null in the caller with a clear failure.
  3. Fix the configuration/script so the deployment id is substituted correctly.

Example fix

// before
eventRepositoryService.setDeploymentTenantId("${deploymentId}", "tenant-acme"); // unsubstituted placeholder
// after
EventDeployment dep = eventRepositoryService.createDeploymentQuery().deploymentName("myEvents").singleResult();
eventRepositoryService.setDeploymentTenantId(dep.getId(), "tenant-acme");
Defensive patterns

Strategy: validation

Validate before calling

if (deploymentId == null || deploymentId.isBlank() || deploymentId.startsWith("${")) {
    throw new IllegalArgumentException("deploymentId unresolved: " + deploymentId);
}

Type guard

boolean hasValidDeploymentId(String id) {
    return id != null && !id.isBlank() && !id.startsWith("${");
}

Try / catch

try {
    eventRepositoryService.setDeploymentTenantId(deploymentId, tenantId);
} catch (FlowableIllegalArgumentException e) {
    log.error("Null/unresolved deploymentId for tenant assignment", e);
}

Prevention

When it happens

Trigger: Calling setDeploymentTenantId with a null deployment id, usually from an unresolved variable, empty query result, or a caller that never captured the deployment id after deployment.

Common situations: Multi-tenant setup scripts where the deploy step failed silently; placeholder values ('${deploymentId}') not substituted in scripted configuration; refactoring dropped the id propagation.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/691ab318e80c55f6. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable-event-registry/src/main/java/org/flowable/eventregistry/impl/cmd/SetDeploymentTenantIdCmd.java:46

 * @author Tijs Rademakers
 * @author Joram Barrez
 */
public class SetDeploymentTenantIdCmd implements Command<Void>, Serializable {

    private static final long serialVersionUID = 1L;

    protected String deploymentId;
    protected String newTenantId;

    public SetDeploymentTenantIdCmd(String deploymentId, String newTenantId) {
        this.deploymentId = deploymentId;
        this.newTenantId = newTenantId;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        if (deploymentId == null) {
            throw new FlowableIllegalArgumentException("deploymentId is null");
        }

        // Update all entities

        EventDeploymentEntity deployment = CommandContextUtil.getDeploymentEntityManager(commandContext).findById(deploymentId);
        if (deployment == null) {
            throw new FlowableObjectNotFoundException("Could not find deployment with id " + deploymentId);
        }

        deployment.setTenantId(newTenantId);

        CommandContextUtil.getEventDefinitionEntityManager(commandContext).updateEventDefinitionTenantIdForDeployment(deploymentId, newTenantId);

        // Doing event definitions in memory, cause we need to clear the event definition cache
        List<EventDefinition> eventDefinitions = new EventDefinitionQueryImpl().deploymentId(deploymentId).list();
        for (EventDefinition eventDefinition : eventDefinitions) {
            CommandContextUtil.getEventRegistryConfiguration().getEventDefinitionCache().remove(eventDefinition.getId());
        }

View on GitHub (pinned to d6d39ce1c6)