flowable/flowable-engine · error · FlowableIllegalArgumentException
tenant id is null
Error message
tenant id is null
What it means
FlowableIllegalArgumentException with message "tenant id is null" thrown by CaseInstanceQueryImpl.caseInstanceTenantId(String) when tenantId is null. Tenant filtering is exact-match only; null tenancy cannot be expressed. Pass the tenant id string (empty string is allowed for 'no tenant' semantics per Flowable conventions, null is not).
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/CaseInstanceQueryImpl.java:736
this.referenceType = referenceType;
}
return this;
}
@Override
public CaseInstanceQuery caseInstanceIsCompleteable() {
if (inOrStatement) {
this.currentOrQueryObject.completeable = true;
} else {
this.completeable = true;
}
return this;
}
@Override
public CaseInstanceQueryImpl caseInstanceTenantId(String tenantId) {
if (tenantId == null) {
throw new FlowableIllegalArgumentException("tenant id is null");
}
if (inOrStatement) {
this.currentOrQueryObject.tenantId = tenantId;
} else {
this.tenantId = tenantId;
}
return this;
}
@Override
public CaseInstanceQueryImpl caseInstanceTenantIdLike(String tenantIdLike) {
if (tenantIdLike == null) {
throw new FlowableIllegalArgumentException("tenant id is null");
}
if (inOrStatement) {
this.currentOrQueryObject.tenantIdLike = tenantIdLike;
} else {
this.tenantIdLike = tenantIdLike;View on GitHub (pinned to d6d39ce1c6)
Solutions
- Pass a non-null tenant id string.
- If the query should ignore tenants, omit the tenant filter or use caseInstanceTenantIdWithoutFilter().
- Ensure the tenant context (e.g. from authentication) is propagated to query-building code.
- Caller-side null check before applying the tenant filter.
Example fix
// before
query.caseInstanceTenantId(TenantContext.getTenantId()); // may be null
// after
String tenantId = TenantContext.getTenantId();
if (tenantId != null) {
query.caseInstanceTenantId(tenantId);
} else {
query.caseInstanceTenantIdWithoutFilter();
} Defensive patterns
Strategy: validation
Validate before calling
String tenantId = TenantContext.getTenantId();
if (tenantId != null) { query.caseInstanceTenantId(tenantId); } else { query.caseInstanceTenantIdWithoutFilter(); } Type guard
boolean hasTenant(String t) { return t != null; } Try / catch
try { query.caseInstanceTenantId(tenantId); } catch (FlowableIllegalArgumentException e) { log.warn("tenant id null: {}", e.getMessage()); } Prevention
- Ensure tenant context propagation (headers, auth) in async/scheduled code.
- Use caseInstanceTenantIdWithoutFilter() when tenant filtering is intentionally disabled.
- Fail fast when a tenant-scoped operation runs without tenant context.
When it happens
Trigger: Calling caseInstanceTenantId(null) on a CaseInstanceQuery, commonly in multi-tenant code where the tenant resolver returned null (no authenticated tenant context).
Common situations: Multi-tenant deployments where the security context lost the tenant header; scheduled jobs running without tenant propagation; caseInstanceTenantId vs caseInstanceTenantIdWithoutFilter confusion.
Related errors
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/c9e2ff1e8c38f762.
Report an issue: GitHub.