flowable/flowable-engine · error · FlowableIllegalArgumentException
tenant id is null
Error message
tenant id is null
What it means
HistoricMilestoneInstanceQueryImpl.milestoneInstanceTenantId() rejects a null tenantId with FlowableIllegalArgumentException. Tenant-id filtering must be an exact string; passing null is treated as a programming mistake rather than 'no filter'.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/history/HistoricMilestoneInstanceQueryImpl.java:102
public HistoricMilestoneInstanceQuery milestoneInstanceReachedAfter(Date reachedAfter) {
this.reachedAfter = reachedAfter;
return this;
}
@Override
public HistoricMilestoneInstanceQuery orderByMilestoneName() {
return orderBy(MilestoneInstanceQueryProperty.MILESTONE_NAME);
}
@Override
public HistoricMilestoneInstanceQuery orderByTimeStamp() {
return orderBy(MilestoneInstanceQueryProperty.MILESTONE_TIMESTAMP);
}
@Override
public HistoricMilestoneInstanceQuery milestoneInstanceTenantId(String tenantId) {
if (tenantId == null) {
throw new FlowableIllegalArgumentException("tenant id is null");
}
this.tenantId = tenantId;
return this;
}
@Override
public HistoricMilestoneInstanceQuery milestoneInstanceTenantIdLike(String tenantIdLike) {
if (tenantIdLike == null) {
throw new FlowableIllegalArgumentException("tenant id is null");
}
this.tenantIdLike = tenantIdLike;
return this;
}
@Override
public HistoricMilestoneInstanceQuery milestoneInstanceWithoutTenantId() {
this.withoutTenantId = true;
return this;View on GitHub (pinned to d6d39ce1c6)
Solutions
- Check the tenant id for null before calling milestoneInstanceTenantId and skip the filter if filtering is intended to be global
- Supply the correct tenant id string
- Use tenantIsNotNull() or simply omit tenant filtering if you want all tenants
- Fix the upstream source (header/context extraction) that yields null
Example fix
// before
query.milestoneInstanceTenantId(tenantId).list();
// after
if (tenantId != null) {
query.milestoneInstanceTenantId(tenantId);
}
List<HistoricMilestoneInstance> results = query.list(); Defensive patterns
Strategy: validation
Validate before calling
if (tenantId != null) {
query.milestoneInstanceTenantId(tenantId);
} Type guard
boolean hasTenant(String t) { return t != null && !t.isEmpty(); } Try / catch
try {
query.milestoneInstanceTenantId(tenantId);
} catch (FlowableIllegalArgumentException e) {
if (!"tenant id is null".equals(e.getMessage())) throw e;
// proceed without tenant filter or fail fast with a clearer message
} Prevention
- Null-check tenant ids sourced from headers or tenant contexts before filtering
- Skip tenant filter methods instead of passing null to mean 'no filter'
- Use Objects.requireNonNull with a domain-specific message to fail at the call site
When it happens
Trigger: Calling milestoneInstanceTenantId(null), often from a variable that was supposed to hold the tenant id (e.g. request parameter or tenant context) but is null.
Common situations: Multi-tenant apps where the tenant id comes from a header/context that is absent for unauthenticated or admin paths; API wrappers forwarding nullable parameters.
Related errors
- Must specify a case definition tenant id to migrate
- Set of case instance ids is null
- Plan item definition type is null
- Plan item definition types is null
- EntryCriterionId is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/ead358d8f4fe9215.
Report an issue: GitHub.