{"record":{"id":"16eb4715b70d4d44","repo":"flowable/flowable-engine","slug":"process-instance-tenant-id-is-null-16eb47","errorCode":null,"errorMessage":"process instance tenant id is null","messagePattern":"process instance tenant id is null","errorType":"validation","errorClass":"ActivitiIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable5-engine/src/main/java/org/activiti/engine/impl/HistoricProcessInstanceQueryImpl.java","lineNumber":368,"sourceCode":"    public HistoricProcessInstanceQuery limitProcessInstanceVariables(Integer processInstanceVariablesLimit) {\n        this.processInstanceVariablesLimit = processInstanceVariablesLimit;\n        return this;\n    }\n\n    public Integer getProcessInstanceVariablesLimit() {\n        return processInstanceVariablesLimit;\n    }\n\n    @Override\n    public HistoricProcessInstanceQuery withJobException() {\n        this.withJobException = true;\n        return this;\n    }\n\n    @Override\n    public HistoricProcessInstanceQuery processInstanceTenantId(String tenantId) {\n        if (tenantId == null) {\n            throw new ActivitiIllegalArgumentException(\"process instance tenant id is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.tenantId = tenantId;\n        } else {\n            this.tenantId = tenantId;\n        }\n        return this;\n    }\n\n    @Override\n    public HistoricProcessInstanceQuery processInstanceTenantIdLike(String tenantIdLike) {\n        if (tenantIdLike == null) {\n            throw new ActivitiIllegalArgumentException(\"process instance tenant id is null\");\n        }\n        if (inOrStatement) {\n            this.currentOrQueryObject.tenantIdLike = tenantIdLike;\n        } else {\n            this.tenantIdLike = tenantIdLike;","sourceCodeStart":350,"sourceCodeEnd":386,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable5-engine/src/main/java/org/activiti/engine/impl/HistoricProcessInstanceQueryImpl.java#L350-L386","documentation":"HistoricProcessInstanceQuery.processInstanceTenantId(tenantId) validates that the exact-match tenant filter is non-null. Filtering historic process instances by a null tenant is unsupported, so the library throws ActivitiIllegalArgumentException immediately when building the query. Use processInstanceTenantIdWithoutTenant() for tenantless instances.","triggerScenarios":"Calling processInstanceTenantId(null) — usually a tenant variable resolved from an unauthenticated context, an unset process variable, or a missing request header.","commonSituations":"Multi-tenant apps where background jobs/schedulers run without tenant context; API consumers omitting the tenant header; code migrated from single-tenant versions that now passes null.","solutions":["Pass an actual tenant id string.","Use processInstanceTenantIdWithoutTenant() when you mean 'instances with no tenant'.","Resolve the tenant before query building and fail with your own error if absent (e.g. throw IllegalArgumentException naming the missing header).","Propagate tenant context into async executions and scheduled jobs explicitly."],"exampleFix":"// before\nquery.processInstanceTenantId(secureHeader(\"X-Tenant\")); // null if header absent\n// after\nString tenant = secureHeader(\"X-Tenant\");\nif (tenant == null) {\n    throw new MissingTenantException(\"X-Tenant header required\");\n}\nquery.processInstanceTenantId(tenant);","handlingStrategy":"validation","validationCode":"if (tenantId == null) throw new MissingTenantException(\"tenant id required for processInstanceTenantId()\");","typeGuard":"boolean hasTenant(String t) { return t != null && !t.isEmpty(); }","tryCatchPattern":"try {\n    query.processInstanceTenantId(tenantId);\n} catch (ActivitiIllegalArgumentException e) {\n    if (e.getMessage().contains(\"tenant id is null\")) {\n        query.processInstanceTenantIdWithoutTenant();\n    }\n}","preventionTips":["Resolve tenant before building any query; fail fast with a descriptive error.","Use processInstanceTenantIdWithoutTenant() for tenantless instances.","Ensure schedulers/async executors receive tenant context.","Validate the tenant request header at the API edge."],"tags":["java","activiti","query","tenant","null-argument"],"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"}