flowable/flowable-engine · error · FlowableIllegalArgumentException

deploymentId is null

Error message

deploymentId is null

What it means

Null-argument guard in ChangeDeploymentTenantIdCmd.execute: the command that moves a deployment to a new tenant id was invoked with a null deploymentId, so it aborts before looking up the deployment.

Solutions

  1. Pass a non-null deploymentId to changeDeploymentTenantId().
  2. Null-check the id before invoking the API and fail fast with a meaningful message.
  3. Verify where the id originates (request parameter, config) and why it is null.

Example fix

// before
repositoryService.changeDeploymentTenantId(deploymentId, tenantId); // deploymentId == null
// after
if (deploymentId != null) {
    repositoryService.changeDeploymentTenantId(deploymentId, tenantId);
}
Defensive patterns

Strategy: validation

Validate before calling

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

Try / catch

try {
    repositoryService.changeDeploymentTenantId(deploymentId, tenantId);
} catch (FlowableIllegalArgumentException e) {
    // handle missing deploymentId
}

Prevention

When it happens

Trigger: Executing the command with deploymentId == null, e.g. calling repositoryService.changeDeploymentTenantId(null, newTenantId) or constructing the cmd with a null id.

Common situations: Deployment id sourced from a variable/config that was null; calling the API inside generic code that forwards an optional id without a null check.

Related errors


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

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/ChangeDeploymentTenantIdCmd.java:83

                break;
            case BY_DATE:
                deploymentMergeStrategy = new MergeByDateDeploymentMergeStrategy();
                break;
            default:
                throw new FlowableException("Merge mode '" + mergeMode + "' not found.");
        }
    }

    public ChangeDeploymentTenantIdCmd(String deploymentId, String newTenantId, DeploymentMergeStrategy deploymentMergeStrategy) {
        this.deploymentId = deploymentId;
        this.newTenantId = newTenantId;
        this.deploymentMergeStrategy = deploymentMergeStrategy;
    }

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

        // Update all entities
        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);
        DeploymentEntity deployment = processEngineConfiguration.getDeploymentEntityManager().findById(deploymentId);
        if (deployment == null) {
            throw new FlowableObjectNotFoundException("Could not find deployment with id " + deploymentId, Deployment.class);
        }

        if (Flowable5Util.isFlowable5Deployment(deployment, commandContext)) {
            processEngineConfiguration.getFlowable5CompatibilityHandler().changeDeploymentTenantId(deploymentId, newTenantId);
            return null;
        }

        deploymentMergeStrategy.prepareMerge(commandContext, deploymentId, newTenantId);
        String oldTenantId = deployment.getTenantId();
        deployment.setTenantId(newTenantId);

View on GitHub (pinned to d6d39ce1c6)