flowable/flowable-engine · error · FlowableIllegalArgumentException

Provided tenant id is null

Error message

Provided tenant id is null

What it means

DeadLetterJobQueryImpl.jobTenantId(String) requires a non-null tenant id because it is used as an exact-match filter. Passing null is ambiguous (it could mean 'no filter'), so FlowableIllegalArgumentException is thrown. Omit the call entirely when tenant filtering is not needed.

Source

Thrown at modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/DeadLetterJobQueryImpl.java:532

    }

    @Override
    public DeadLetterJobQueryImpl exceptionMessage(String exceptionMessage) {
        if (exceptionMessage == null) {
            throw new FlowableIllegalArgumentException("Provided exception message is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.exceptionMessage = exceptionMessage;
        } else {
            this.exceptionMessage = exceptionMessage;
        }
        return this;
    }

    @Override
    public DeadLetterJobQueryImpl jobTenantId(String tenantId) {
        if (tenantId == null) {
            throw new FlowableIllegalArgumentException("Provided tenant id is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.tenantId = tenantId;
        } else {
            this.tenantId = tenantId;
        }
        return this;
    }

    @Override
    public DeadLetterJobQueryImpl jobTenantIdLike(String tenantIdLike) {
        if (tenantIdLike == null) {
            throw new FlowableIllegalArgumentException("Provided tenant id is null");
        }
        if (inOrStatement) {
            this.currentOrQueryObject.tenantIdLike = tenantIdLike;
        } else {
            this.tenantIdLike = tenantIdLike;

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Only apply the tenant filter when a tenant id is resolved
  2. Default to a valid tenant id constant for system-level queries
  3. Use jobTenantIdLike or omit filtering if you need cross-tenant results
  4. Handle FlowableIllegalArgumentException at the service boundary

Example fix

// before
query.jobTenantId(tenantContext.getCurrentTenantId()); // null for system calls
// after
String tenantId = tenantContext.getCurrentTenantId();
if (tenantId != null) {
    query.jobTenantId(tenantId);
}
Defensive patterns

Strategy: validation

Validate before calling

if (tenantId != null) { query.jobTenantId(tenantId); }

Type guard

boolean hasTenant(String t) { return t != null; }

Try / catch

try { query.jobTenantId(tenantId); } catch (FlowableIllegalArgumentException e) { log.warn("No tenant id resolved; querying without tenant filter", e); }

Prevention

When it happens

Trigger: Calling deadLetterJobQuery().jobTenantId(tenantId) where tenantId is null, e.g. from an unauthenticated request context or missing tenant resolution.

Common situations: Multi-tenant applications where the tenant provider returns null for unauthenticated/system contexts; configuration keys for tenant id not set in the environment.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/9a2cc41325b19cad. Report an issue: GitHub.