flowable/flowable-engine · error · ActivitiIllegalArgumentException

DeploymentId is null

Error message

DeploymentId is null

What it means

ModelQueryImpl.deploymentId(String) narrows the model query to models deployed with a specific deployment. Flowable throws ActivitiIllegalArgumentException when the deploymentId is null, since a null id cannot be used as an equality filter in the generated SQL.

Source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/ModelQueryImpl.java:138

        if (version == null) {
            throw new ActivitiIllegalArgumentException("version is null");
        } else if (version <= 0) {
            throw new ActivitiIllegalArgumentException("version must be positive");
        }
        this.version = version;
        return this;
    }

    @Override
    public ModelQuery latestVersion() {
        this.latest = true;
        return this;
    }

    @Override
    public ModelQuery deploymentId(String deploymentId) {
        if (deploymentId == null) {
            throw new ActivitiIllegalArgumentException("DeploymentId is null");
        }
        this.deploymentId = deploymentId;
        return this;
    }

    @Override
    public ModelQuery notDeployed() {
        if (deployed) {
            throw new ActivitiIllegalArgumentException("Invalid usage: cannot use deployed() and notDeployed() in the same query");
        }
        this.notDeployed = true;
        return this;
    }

    @Override
    public ModelQuery deployed() {
        if (notDeployed) {
            throw new ActivitiIllegalArgumentException("Invalid usage: cannot use deployed() and notDeployed() in the same query");

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Pass a non-null, existing deployment id (e.g. from Deployment.getId()).
  2. Null-check the deployment object/id before calling deploymentId().
  3. If no deployment filter is desired, skip the deploymentId() call.
  4. Wrap query construction in try-catch for ActivitiIllegalArgumentException to handle it gracefully.

Example fix

// before
Deployment d = repoService.createDeploymentQuery().deploymentName(name).singleResult();
query.deploymentId(d.getId()); // NPE-free but getId() may be fine; d may be null
// after
Deployment d = repoService.createDeploymentQuery().deploymentName(name).singleResult();
if (d != null) {
    query.deploymentId(d.getId());
}
Defensive patterns

Strategy: validation

Validate before calling

if (deploymentId != null && !deploymentId.isEmpty()) {
    query.deploymentId(deploymentId);
}

Type guard

boolean hasDeploymentId(Deployment d) { return d != null && d.getId() != null; }

Try / catch

try {
    query.deploymentId(deploymentId);
} catch (org.activiti.engine.ActivitiIllegalArgumentException e) {
    throw new BadRequestException("deploymentId filter requires a non-null id", e);
}

Prevention

When it happens

Trigger: Calling modelQuery.deploymentId(null) — typically when the deployment id variable is null because no deployment was found or created yet.

Common situations: Looking up a Deployment via a repositoryService query that returned null and passing the result straight through; refactoring code where a deployment id field was never initialized.

Related errors


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