{"record":{"id":"c67accd3fafe7cae","repo":"flowable/flowable-engine","slug":"app-definition-tenantid-is-null","errorCode":null,"errorMessage":"app definition tenantId is null","messagePattern":"app definition tenantId is null","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-app-engine/src/main/java/org/flowable/app/engine/impl/repository/AppDefinitionQueryImpl.java","lineNumber":236,"sourceCode":"\n    protected void checkVersion(Integer version) {\n        if (version == null) {\n            throw new FlowableIllegalArgumentException(\"version is null\");\n        } else if (version <= 0) {\n            throw new FlowableIllegalArgumentException(\"version must be positive\");\n        }\n    }\n\n    @Override\n    public AppDefinitionQueryImpl latestVersion() {\n        this.latest = true;\n        return this;\n    }\n\n    @Override\n    public AppDefinitionQuery appDefinitionTenantId(String tenantId) {\n        if (tenantId == null) {\n            throw new FlowableIllegalArgumentException(\"app definition tenantId is null\");\n        }\n        this.tenantId = tenantId;\n        return this;\n    }\n\n    @Override\n    public AppDefinitionQuery appDefinitionTenantIdLike(String tenantIdLike) {\n        if (tenantIdLike == null) {\n            throw new FlowableIllegalArgumentException(\"app definition tenantId is null\");\n        }\n        this.tenantIdLike = tenantIdLike;\n        return this;\n    }\n\n    @Override\n    public AppDefinitionQuery appDefinitionWithoutTenantId() {\n        this.withoutTenantId = true;\n        return this;","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-app-engine/src/main/java/org/flowable/app/engine/impl/repository/AppDefinitionQueryImpl.java#L218-L254","documentation":"appDefinitionTenantId() filters app definitions by exact tenant id and rejects null, because the subsequent SQL equality comparison requires a concrete tenant id value. Flowable throws FlowableIllegalArgumentException early at query-construction time rather than returning empty or broken results.","triggerScenarios":"Calling AppDefinitionQuery.appDefinitionTenantId(null) — typically when the tenant is resolved from a security context, header, or authenticated user and the resolution returned null.","commonSituations":"Multi-tenant apps where the tenant header is missing; code running outside a tenant-aware context (e.g. background jobs); security context not yet populated when the query is built.","solutions":["Pass the actual tenant id string; verify tenant resolution returns a value before querying.","Skip the tenant filter if querying across tenants is intended (requires appropriate authorization).","Throw or return a clear 'tenant required' error in your own layer instead of passing null into the query."],"exampleFix":"// before\nString tenantId = securityContext.getTenantId(); // may be null\nAppDefinition definition = repositoryService.createAppDefinitionQuery()\n    .appDefinitionTenantId(tenantId).latestVersion().singleResult();\n\n// after\nString tenantId = securityContext.getTenantId();\nif (tenantId == null) {\n    throw new IllegalStateException(\"No tenant resolved for current request\");\n}\nAppDefinition definition = repositoryService.createAppDefinitionQuery()\n    .appDefinitionTenantId(tenantId).latestVersion().singleResult();","handlingStrategy":"validation","validationCode":"if (tenantId == null || tenantId.isEmpty()) { throw new IllegalStateException(\"tenant id is required\"); }","typeGuard":"boolean hasTenant(String t) { return t != null && !t.trim().isEmpty(); }","tryCatchPattern":"try { query.appDefinitionTenantId(tenantId); } catch (FlowableIllegalArgumentException e) { throw new ResponseStatusException(HttpStatus.BAD_REQUEST, \"tenant id required\"); }","preventionTips":["Resolve and validate the tenant id once at the start of the request, before building queries.","In multi-tenant apps, fail fast with a clear 'tenant missing' error in your own layer.","For background jobs, configure an explicit tenant id instead of relying on the security context."],"tags":["flowable","null-argument","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-14T11:17:12.474Z"}