flowable/flowable-engine · error · FlowableIllegalArgumentException
Tenant id is null
Error message
Tenant id is null
What it means
PlanItemInstanceQueryImpl.planItemInstanceTenantId(String) throws FlowableIllegalArgumentException when the tenantId string is null. Tenant id is a required, validated filter; a null value would produce an ambiguous query, so the API rejects it eagerly.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/PlanItemInstanceQueryImpl.java:873
}
@Override
public PlanItemInstanceQuery involvedGroups(Collection<String> involvedGroups) {
if (involvedGroups == null) {
throw new FlowableIllegalArgumentException("involvedGroups is null");
}
if (inOrStatement) {
this.currentOrQueryObject.involvedGroups = involvedGroups;
} else {
this.involvedGroups = involvedGroups;
}
return this;
}
@Override
public PlanItemInstanceQuery planItemInstanceTenantId(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 PlanItemInstanceQuery planItemInstanceWithoutTenantId() {
if (inOrStatement) {
this.currentOrQueryObject.withoutTenantId = true;
} else {
this.withoutTenantId = true;
}
return this;
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Pass an actual tenant id string; to query across tenants, omit the planItemInstanceTenantId call instead of passing null.
- Resolve the tenant id first and skip the call when absent: if (tenantId != null) query.planItemInstanceTenantId(tenantId).
- Use planItemInstanceTenantIdLike if a pattern match over tenants is intended.
Example fix
// before
query.planItemInstanceTenantId(TenantContext.getTenantId()); // may be null
// after
String tenantId = TenantContext.getTenantId();
if (tenantId != null) {
query.planItemInstanceTenantId(tenantId);
} Defensive patterns
Strategy: validation
Validate before calling
if (tenantId == null || tenantId.isEmpty()) { skipTenantFilter = true; } Try / catch
try { query.planItemInstanceTenantId(tenantId); } catch (FlowableIllegalArgumentException e) { throw new IllegalStateException("No tenant context available for query", e); } Prevention
- Resolve tenant context explicitly and skip the tenant filter when absent.
- Never rely on a tenant resolver that can silently return null in system/background threads.
When it happens
Trigger: Calling planItemInstanceTenantId(null), e.g. when the tenant id is taken from an unauthenticated context, a missing header, or a TenantContext/tenant resolver that returns null.
Common situations: Multi-tenant applications where code runs outside a tenant context (background jobs, system tasks) and tenant resolution returns null; copying query-builder code where the tenant is sometimes not filtered.
Related errors
- tenant id is null
- Must specify a case definition tenant id to migrate
- query is null
- parentScopeIds is null or empty
- Business status is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/5f08451f1f587ae4.
Report an issue: GitHub.