flowable/flowable-engine · error · ActivitiIllegalArgumentException

Model tenant id is null

Error message

Model tenant id is null

What it means

ModelQueryImpl.modelTenantId(String) filters models by an exact tenant id for multi-tenant deployments. Flowable throws ActivitiIllegalArgumentException when the tenantId is null, because a null tenant cannot form a valid equality filter.

Source

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

            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");
        }
        this.deployed = true;
        return this;
    }

    @Override
    public ModelQuery modelTenantId(String tenantId) {
        if (tenantId == null) {
            throw new ActivitiIllegalArgumentException("Model tenant id is null");
        }
        this.tenantId = tenantId;
        return this;
    }

    @Override
    public ModelQuery modelTenantIdLike(String tenantIdLike) {
        if (tenantIdLike == null) {
            throw new ActivitiIllegalArgumentException("Model tenant id is null");
        }
        this.tenantIdLike = tenantIdLike;
        return this;
    }

    @Override
    public ModelQuery modelWithoutTenantId() {
        this.withoutTenantId = true;
        return this;

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Pass a valid, non-null tenant id that exists in the deployment.
  2. Null-check the tenant id (from context/config) before applying the filter; skip the filter if tenant filtering is not needed.
  3. Set a default tenant id (e.g. "" or a configured default) when tenant context is absent.
  4. Catch ActivitiIllegalArgumentException around query building to return a clear error to the client.

Example fix

// before
query.modelTenantId(tenantContext.getTenantId()); // may be null
// after
String tenantId = tenantContext.getTenantId();
if (tenantId != null) {
    query.modelTenantId(tenantId);
}
Defensive patterns

Strategy: validation

Validate before calling

String tenantId = tenantContext.getTenantId();
if (tenantId != null) {
    query.modelTenantId(tenantId);
}

Type guard

boolean hasTenant(String t) { return t != null && !t.isEmpty(); }

Try / catch

try {
    query.modelTenantId(tenantId);
} catch (org.activiti.engine.ActivitiIllegalArgumentException e) {
    throw new BadRequestException("tenant id is required for this query", e);
}

Prevention

When it happens

Trigger: Calling modelQuery.modelTenantId(null) — usually when the tenant id comes from an unset context (e.g. TenantContext or request header absent).

Common situations: Multi-tenant apps where the authenticated user has no tenant assigned; configuration or environment variable for tenant id missing; single-tenant setups that still call the tenant filter with null.

Related errors


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