flowable/flowable-engine · error · FlowableIllegalArgumentException

deploymentId is null

Error message

deploymentId is null

What it means

SetDeploymentTenantIdCmd.execute validates its deploymentId argument up front and throws FlowableIllegalArgumentException when it is null. The command refuses to run a tenant-id update that could never resolve to a deployment.

Source

Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/cmd/SetDeploymentTenantIdCmd.java:45

/**
 * @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

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

        deployment.setTenantId(newTenantId);

        // Doing process instances, executions and tasks with direct SQL updates
        // (otherwise would not be performant)
        CommandContextUtil.getDecisionEntityManager(commandContext).updateDecisionTenantIdForDeployment(deploymentId, newTenantId);

        // Doing decision tables in memory, cause we need to clear the decision table cache
        List<DmnDecision> decisionTables = new DecisionQueryImpl().deploymentId(deploymentId).list();
        for (DmnDecision decisionTable : decisionTables) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Check deploymentId for null/blank before constructing or executing the command.
  2. Ensure the id source (query result, config, request) is validated at the caller boundary.
  3. Catch FlowableIllegalArgumentException to surface a clear client-side validation error.

Example fix

// before
managementService.executeCommand(new SetDeploymentTenantIdCmd(deploymentId, tenantId));
// after
Objects.requireNonNull(deploymentId, "deploymentId must be set");
managementService.executeCommand(new SetDeploymentTenantIdCmd(deploymentId, tenantId));
Defensive patterns

Strategy: validation

Validate before calling

if (deploymentId == null || deploymentId.trim().isEmpty()) {
    throw new IllegalArgumentException("deploymentId must be non-empty");
}

Try / catch

try {
    dmnManagementService.executeCommand(new SetDeploymentTenantIdCmd(deploymentId, tenantId));
} catch (FlowableIllegalArgumentException e) {
    log.error("Invalid argument for tenant update", e);
}

Prevention

When it happens

Trigger: Constructing SetDeploymentTenantIdCmd with a null deploymentId — typically because the caller's own id variable was never set, or a lookup that returned null was passed straight through.

Common situations: Chaining deployment.getId() from an object that was null; refactoring that removed id assignment; programmatic command execution where arguments come from config or request parameters that were absent.

Related errors


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