flowable/flowable-engine · error · ActivitiIllegalArgumentException
process definition tenantId is null
Error message
process definition tenantId is null
What it means
Flowable/Activiti query builders validate arguments eagerly. processDefinitionTenantIdLike() throws ActivitiIllegalArgumentException when the tenantIdLike parameter is null, because a null 'like' filter cannot be translated to a meaningful SQL predicate.
Source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/ProcessDefinitionQueryImpl.java:265
@Override
public ProcessDefinitionQuery suspended() {
this.suspensionState = SuspensionState.SUSPENDED;
return this;
}
@Override
public ProcessDefinitionQuery processDefinitionTenantId(String tenantId) {
if (tenantId == null) {
throw new ActivitiIllegalArgumentException("processDefinition tenantId is null");
}
this.tenantId = tenantId;
return this;
}
@Override
public ProcessDefinitionQuery processDefinitionTenantIdLike(String tenantIdLike) {
if (tenantIdLike == null) {
throw new ActivitiIllegalArgumentException("process definition tenantId is null");
}
this.tenantIdLike = tenantIdLike;
return this;
}
@Override
public ProcessDefinitionQuery processDefinitionWithoutTenantId() {
this.withoutTenantId = true;
return this;
}
@Override
public ProcessDefinitionQuery messageEventSubscription(String messageName) {
return eventSubscription("message", messageName);
}
@Override
public ProcessDefinitionQuery messageEventSubscriptionName(String messageName) {View on GitHub (pinned to d6d39ce1c6)
Solutions
- Pass a non-null tenant id string to processDefinitionTenantIdLike()
- If the intent is 'any tenant', omit the tenant filter entirely or use the tenantIdLike value '*' (all tenants) instead of null
- Guard the caller: only add the tenant filter when a tenant id is actually available
- Catch ActivitiIllegalArgumentException around query construction to surface a clear 400-style message
Example fix
// before
query.processDefinitionTenantIdLike(tenantCtx.getTenantId()); // tenantId may be null
// after
if (tenantCtx.getTenantId() != null) {
query.processDefinitionTenantIdLike(tenantCtx.getTenantId());
} Defensive patterns
Strategy: validation
Validate before calling
if (tenantIdLike == null) {
throw new IllegalArgumentException("tenantIdLike must not be null");
}
query.processDefinitionTenantIdLike(tenantIdLike); Type guard
boolean hasTenantId(String t) { return t != null && !t.trim().isEmpty(); } Try / catch
try {
query.processDefinitionTenantIdLike(tenantId);
} catch (ActivitiIllegalArgumentException e) {
if (e.getMessage().contains("tenantId")) {
throw new InvalidRequestException("tenantId is required");
}
throw e;
} Prevention
- Resolve tenant id from a single validated source (header/token) before querying
- Use a helper that applies tenant filters only when a tenant is present
- Add unit tests for null-tenant query construction
- Prefer '*' or no filter over null for 'all tenants' semantics
When it happens
Trigger: Calling ProcessDefinitionQuery.processDefinitionTenantIdLike(null), typically when the tenant id comes from an uninitialized variable, a config property that is missing, or a TenantContext that returned null.
Common situations: Multi-tenant apps where the tenant id is resolved from a header/token at runtime and is absent for anonymous or misconfigured requests; unit tests constructing queries without setting tenant context.
Related errors
- version is null
- Deployment id is null
- deploymentName is null
- deploymentNameLike is null
- deploymentCategory is null
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/3de82eb5a3b14a1a.
Report an issue: GitHub.