{"record":{"id":"4e107de899c839c5","repo":"quarkusio/quarkus","slug":"method-tenantresolver-getdefaulttenantid-retur","errorCode":null,"errorMessage":"Method 'TenantResolver.getDefaultTenantId()' returned a null value. This violates the contract of the interface!","messagePattern":"Method 'TenantResolver\\.getDefaultTenantId\\(\\)' returned a null value\\. This violates the contract of the interface!","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/tenant/HibernateMultiTenantConnectionProvider.java","lineNumber":58,"sourceCode":"        InstanceHandle<TenantResolver> tenantResolver = tenantResolver(persistenceUnitName);\n        String tenantId;\n        // Activate RequestScope if the TenantResolver is @RequestScoped or @SessionScoped\n        ManagedContext requestContext = Arc.container().requestContext();\n        Class<? extends Annotation> tenantScope = tenantResolver.getBean().getScope();\n        boolean requiresRequestScope = (tenantScope == RequestScoped.class || tenantScope == SessionScoped.class);\n        boolean forceRequestActivation = (!requestContext.isActive() && requiresRequestScope);\n        try {\n            if (forceRequestActivation) {\n                requestContext.activate();\n            }\n            tenantId = tenantResolver.get().getDefaultTenantId();\n        } finally {\n            if (forceRequestActivation) {\n                requestContext.deactivate();\n            }\n        }\n        if (tenantId == null) {\n            throw new IllegalStateException(\"Method 'TenantResolver.getDefaultTenantId()' returned a null value. \"\n                    + \"This violates the contract of the interface!\");\n        }\n        return selectConnectionProvider(tenantId);\n    }\n\n    @Override\n    protected ConnectionProvider selectConnectionProvider(final String tenantIdentifier) {\n        LOG.debugv(\"selectConnectionProvider(persistenceUnitName={0}, tenantIdentifier={1})\", persistenceUnitName,\n                tenantIdentifier);\n\n        ConnectionProvider provider = providerMap.get(tenantIdentifier);\n        if (provider == null) {\n            final ConnectionProvider connectionProvider = resolveConnectionProvider(persistenceUnitName, tenantIdentifier);\n            providerMap.put(tenantIdentifier, connectionProvider);\n            return connectionProvider;\n        }\n        return provider;\n","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/tenant/HibernateMultiTenantConnectionProvider.java#L40-L76","documentation":"TenantResolver.getDefaultTenantId() must return a non-null tenant id; this is the interface contract. Quarkus throws IllegalStateException when it returns null while fetching the connection provider for a tenant connection in a multi-tenant persistence unit.","triggerScenarios":"Multi-tenant Hibernate ORM is active, getDefaultTenantId() is invoked (e.g., when the tenant connection provider must fall back to the default tenant / 'any' connection provider), and the user implementation returns null.","commonSituations":"Tenant id source not populated yet (e.g., reading tenant from a request header outside of an active request context, no request scope, Vert.x context absent); resolver method returns null instead of a default tenant; missing @ActivateRequestContext or context propagation.","solutions":["Fix getDefaultTenantId() to always return a non-null value (provide a real default tenant)","If tenant comes from the request, ensure the call happens inside an active request context or capture it earlier","Throw a domain-specific exception when the tenant is truly unknown instead of returning null","Add a test covering unauthenticated/no-tenant requests"],"exampleFix":"// before\n@Override\npublic String getDefaultTenantId() {\n    return httpHeaders.getHeaderString(\"X-Tenant\"); // may be null\n}\n\n// after\n@Override\npublic String getDefaultTenantId() {\n    String tenant = httpHeaders.getHeaderString(\"X-Tenant\");\n    if (tenant == null) {\n        throw new WebApplicationException(\"Missing tenant\", 400);\n    }\n    return tenant;\n}","handlingStrategy":"validation","validationCode":"String tenant = resolveTenantFromContext();\nif (tenant == null || tenant.isBlank()) {\n    throw new IllegalStateException(\"Tenant id must not be null/blank before Hibernate calls\");\n}","typeGuard":"boolean validTenant(String t) { return t != null && !t.isBlank(); }","tryCatchPattern":"try {\n    return session.withTransaction(s -> s.find(E.class, id)).await().indefinitely();\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"getDefaultTenantId\")) { logMissingTenant(); }\n    throw e;\n}","preventionTips":["Never return null from TenantResolver methods — throw a domain exception instead","Ensure tenant extraction happens inside the active request/Vert.x context","Test the no-authenticated-user path explicitly"],"tags":["hibernate-orm","multi-tenancy","null-return","contract-violation"],"backgroundTag":"tenant-resolver-returned-null","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}