flowable/flowable-engine · error · FlowableIllegalArgumentException
deploymentTenantId is null
Error message
deploymentTenantId is null
What it means
AppDeploymentQueryImpl.deploymentTenantId(String) throws FlowableIllegalArgumentException when the tenantId argument is null. The Flowable query builders validate each criterion eagerly at setter time so that an invalid query fails at construction rather than producing a broken SQL query at execution. Passing null for an exact tenant filter is not a supported way to express 'no filter' — simply omit the call instead.
Solutions
- Ensure a non-null tenant id is resolved before building the query (e.g. require the tenantId request parameter or resolve it from the authenticated principal)
- Only call deploymentTenantId(...) when the value is non-null; omit it to query across all tenants
- If a default tenant is acceptable, fall back to a constant (e.g. "default") when the resolved id is null
Example fix
// before
query.deploymentTenantId(tenantContext.getTenantId());
// after
String tenantId = tenantContext.getTenantId();
if (tenantId != null) {
query.deploymentTenantId(tenantId);
} Defensive patterns
Strategy: validation
Validate before calling
if (tenantId == null || tenantId.isEmpty()) {
throw new IllegalArgumentException("tenantId must be provided for deploymentTenantId filter, or omit the filter");
}
query.deploymentTenantId(tenantId); Type guard
boolean hasTenant = tenantId instanceof String s && !s.isEmpty();
Try / catch
try {
query.deploymentTenantId(tenantId);
} catch (FlowableIllegalArgumentException e) {
// tenantId was null — build query without tenant filter or rethrow with context
logger.warn("No tenant id resolved; querying all tenants", e);
} Prevention
- Resolve tenant context before query construction
- Use an Optional<String> and only set the filter when present
- Never pass null as a query criterion — omit the setter instead
When it happens
Trigger: Calling appDeploymentService.createDeploymentQuery().deploymentTenantId(null), typically when the tenant id is supplied by a variable, request parameter, or config value that is null at query time.
Common situations: REST/API layers forwarding a missing tenantId query parameter; multi-tenant apps where TenantContext.getTenantId() returns null before tenant resolution; refactoring that replaced an optional-tenant path with an unconditional setter call.
Related errors
- callbackId is null
- Candidate group is null
- Candidate group list is null
- Candidate user is null
- Deployment id is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/007f0d8d2ff2cbbb.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-app-engine/src/main/java/org/flowable/app/engine/impl/repository/AppDeploymentQueryImpl.java:123
throw new FlowableIllegalArgumentException("deploymentCategoryExclude is null");
}
this.categoryNotEquals = deploymentCategoryNotEquals;
return this;
}
@Override
public AppDeploymentQueryImpl deploymentKey(String deploymentKey) {
if (deploymentKey == null) {
throw new FlowableIllegalArgumentException("deploymentKey is null");
}
this.key = deploymentKey;
return this;
}
@Override
public AppDeploymentQueryImpl deploymentTenantId(String tenantId) {
if (tenantId == null) {
throw new FlowableIllegalArgumentException("deploymentTenantId is null");
}
this.tenantId = tenantId;
return this;
}
@Override
public AppDeploymentQueryImpl deploymentTenantIdLike(String tenantIdLike) {
if (tenantIdLike == null) {
throw new FlowableIllegalArgumentException("deploymentTenantIdLike is null");
}
this.tenantIdLike = tenantIdLike;
return this;
}
@Override
public AppDeploymentQueryImpl deploymentWithoutTenantId() {
this.withoutTenantId = true;
return this;View on GitHub (pinned to d6d39ce1c6)