{"record":{"id":"1a5864381c548dd0","repo":"flowable/flowable-engine","slug":"processdefinition-tenantid-is-null-1a5864","errorCode":null,"errorMessage":"processDefinition tenantId is null","messagePattern":"processDefinition tenantId is null","errorType":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/ProcessDefinitionQueryImpl.java","lineNumber":256,"sourceCode":"        return this;\n    }\n\n    @Override\n    public ProcessDefinitionQuery active() {\n        this.suspensionState = SuspensionState.ACTIVE;\n        return this;\n    }\n\n    @Override\n    public ProcessDefinitionQuery suspended() {\n        this.suspensionState = SuspensionState.SUSPENDED;\n        return this;\n    }\n\n    @Override\n    public ProcessDefinitionQuery processDefinitionTenantId(String tenantId) {\n        if (tenantId == null) {\n            throw new ActivitiIllegalArgumentException(\"processDefinition tenantId is null\");\n        }\n        this.tenantId = tenantId;\n        return this;\n    }\n\n    @Override\n    public ProcessDefinitionQuery processDefinitionTenantIdLike(String tenantIdLike) {\n        if (tenantIdLike == null) {\n            throw new ActivitiIllegalArgumentException(\"process definition tenantId is null\");\n        }\n        this.tenantIdLike = tenantIdLike;\n        return this;\n    }\n\n    @Override\n    public ProcessDefinitionQuery processDefinitionWithoutTenantId() {\n        this.withoutTenantId = true;\n        return this;","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/ProcessDefinitionQueryImpl.java#L238-L274","documentation":"ProcessDefinitionQueryImpl.processDefinitionTenantId(String) throws ActivitiIllegalArgumentException 'processDefinition tenantId is null' when the tenantId argument is null. In multi-tenant Flowable setups the tenant filter must be a concrete (possibly empty-string-means-no-tenant) value; null is rejected eagerly to keep the SQL predicate valid. This is a client-side argument contract violation.","triggerScenarios":"Calling ProcessDefinitionQuery.processDefinitionTenantId(null) — commonly when the tenant id comes from a security context, request header, or tenant resolver that returned null (e.g. code running outside a tenant-aware context).","commonSituations":"Multi-tenant apps where background jobs/schedulers have no tenant context; missing X-Tenant-ID header forwarding; tenantId field absent in config or JWT claims; migrating single-tenant code into a multi-tenant deployment.","solutions":["Resolve the tenant id from the authenticated context before building the query; fail fast if absent","If the intent is 'no tenant', pass the empty string \"\" (the engine convention) rather than null","Make the tenant filter conditional when tenant isolation is not required","Catch ActivitiIllegalArgumentException and return a clear 'tenant required' error"],"exampleFix":"// before\nquery.processDefinitionTenantId(tenantContext.currentTenantId()); // null in scheduler\n// after\nString tenantId = tenantContext.currentTenantId();\nif (tenantId != null) {\n    query.processDefinitionTenantId(tenantId);\n} else {\n    query.processDefinitionTenantIdWithoutTenant();\n}","handlingStrategy":"validation","validationCode":"if (tenantId == null) throw new IllegalArgumentException(\"tenantId is required (use \\\"\\\" for no tenant)\");\nquery.processDefinitionTenantId(tenantId);","typeGuard":"boolean hasTenantContext(String t) { return t != null; }","tryCatchPattern":"try {\n    query.processDefinitionTenantId(tenantId);\n} catch (ActivitiIllegalArgumentException e) {\n    if (e.getMessage().contains(\"tenantId is null\")) {\n        throw new BadRequestException(\"tenant context is required for this query\");\n    }\n    throw e;\n}","preventionTips":["Resolve tenant ids from the security/tenant context and fail fast when absent","Use processDefinitionTenantIdWithoutTenant() or \"\" instead of null for no-tenant queries","Ensure background jobs propagate or re-establish tenant context","Validate tenant headers/claims at the entry point of every request"],"tags":["java","null-argument","query-builder","activiti","multi-tenancy"],"backgroundTag":"null-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}