{"record":{"id":"a4f56fed21a3bbe3","repo":"flowable/flowable-engine","slug":"model-tenant-id-is-null","errorCode":null,"errorMessage":"Model tenant id is null","messagePattern":"Model tenant id is null","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/ModelQueryImpl.java","lineNumber":167,"sourceCode":"            throw new FlowableIllegalArgumentException(\"Invalid usage: cannot use deployed() and notDeployed() in the same query\");\n        }\n        this.notDeployed = true;\n        return this;\n    }\n\n    @Override\n    public ModelQuery deployed() {\n        if (notDeployed) {\n            throw new FlowableIllegalArgumentException(\"Invalid usage: cannot use deployed() and notDeployed() in the same query\");\n        }\n        this.deployed = true;\n        return this;\n    }\n\n    @Override\n    public ModelQuery modelTenantId(String tenantId) {\n        if (tenantId == null) {\n            throw new FlowableIllegalArgumentException(\"Model tenant id is null\");\n        }\n        this.tenantId = tenantId;\n        return this;\n    }\n\n    @Override\n    public ModelQuery modelTenantIdLike(String tenantIdLike) {\n        if (tenantIdLike == null) {\n            throw new FlowableIllegalArgumentException(\"Model tenant id is null\");\n        }\n        this.tenantIdLike = tenantIdLike;\n        return this;\n    }\n\n    @Override\n    public ModelQuery modelWithoutTenantId() {\n        this.withoutTenantId = true;\n        return this;","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/ModelQueryImpl.java#L149-L185","documentation":"ModelQueryImpl.modelTenantId() filters models by an exact tenant id, which must be a non-null String. A null tenant id cannot form a valid tenant filter, so the library throws FlowableIllegalArgumentException immediately. Multi-tenant Flowable deployments require an explicit tenant value here — empty string is allowed but null is not.","triggerScenarios":"Calling ModelQuery.modelTenantId(null), typically when the tenant id comes from an unset configuration property, a request header that was absent, or a tenant context holder that was never populated for the current thread.","commonSituations":"Multi-tenant applications where the tenant resolver returns null for unauthenticated/background threads (scheduled jobs, async executors); Spring config property not set; tenant header missing in an incoming REST request.","solutions":["Resolve the tenant id before querying and fail earlier with a clear message if it is missing.","Guard the call: if (tenantId != null) query.modelTenantId(tenantId);","Ensure background/scheduled code runs inside a properly initialized tenant context.","If querying across tenants is intended, omit modelTenantId() entirely instead of passing null."],"exampleFix":"// before\nModelQuery query = repositoryService.createModelQuery()\n    .modelTenantId(tenantContext.getTenantId()); // null in background job\n\n// after\nString tenantId = tenantContext.getTenantId();\nModelQuery query = repositoryService.createModelQuery();\nif (tenantId != null) {\n    query.modelTenantId(tenantId);\n} else {\n    throw new IllegalStateException(\"No tenant context for model query\");\n}","handlingStrategy":"validation","validationCode":"if (tenantId == null || tenantId.isEmpty()) {\n    throw new IllegalStateException(\"Tenant context missing; cannot query models by tenant\");\n}\nModel model = repositoryService.createModelQuery().modelTenantId(tenantId).singleResult();","typeGuard":"boolean hasTenantId(String tenantId) {\n    return tenantId != null && !tenantId.trim().isEmpty();\n}","tryCatchPattern":"try {\n    return repositoryService.createModelQuery().modelTenantId(tenantId).list();\n} catch (FlowableIllegalArgumentException e) {\n    log.error(\"Tenant id was null when querying models: {}\", e.getMessage());\n    throw new MissingTenantContextException();\n}","preventionTips":["Initialize the tenant context for every thread, including scheduled jobs and async executors.","Make tenant id a required request header/parameter validated at the API edge.","Omit the tenant filter deliberately when cross-tenant queries are intended.","Fail fast on missing tenant config at application startup."],"tags":["flowable","query-builder","tenant","null-check"],"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"}