{"record":{"id":"933e845fafa07aa3","repo":"quarkusio/quarkus","slug":"multiple-beans-found-for-localized-interface-e-v","errorCode":null,"errorMessage":"Multiple beans found for localized interface [{e.value}] and locale [{e.key}]","messagePattern":"Multiple beans found for localized interface \\[(.+?)\\] and locale \\[(.+?)\\]","errorType":"exception","errorClass":"java.lang.IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/qute/runtime/src/main/java/io/quarkus/qute/i18n/MessageBundles.java","lineNumber":123,"sourceCode":"        ArcContainer container = Arc.container();\n        // For every bundle register a new resolver\n        for (Entry<String, Map<String, Class<?>>> entry : context.get().getBundleInterfaces().entrySet()) {\n            final String bundleName = entry.getKey();\n            final Map<String, Resolver> interfaces = new HashMap<>();\n            Resolver resolver = null;\n            for (Entry<String, Class<?>> locEntry : entry.getValue().entrySet()) {\n                if (locEntry.getKey().equals(DEFAULT_LOCALE)) {\n                    resolver = (Resolver) container.select(locEntry.getValue(), Default.Literal.INSTANCE).get();\n                    continue;\n                }\n                Instance<?> found = container.select(locEntry.getValue(), new Localized.Literal(locEntry.getKey()));\n                if (found.isUnsatisfied()) {\n                    throw new IllegalStateException(\n                            Qute.fmt(\"Bean not found for localized interface [{e.value}] and locale [{e.key}]\")\n                                    .data(\"e\", locEntry).render());\n                }\n                if (found.isAmbiguous()) {\n                    throw new IllegalStateException(\n                            Qute.fmt(\"Multiple beans found for localized interface [{e.value}] and locale [{e.key}]\")\n                                    .data(\"e\", locEntry).render());\n                }\n                interfaces.put(locEntry.getKey(), (Resolver) found.get());\n            }\n            final Resolver defaultResolver = resolver;\n\n            builder.addNamespaceResolver(new NamespaceResolver() {\n                @Override\n                public CompletionStage<Object> resolve(EvalContext context) {\n                    Object locale = context.getAttribute(ATTRIBUTE_LOCALE);\n                    if (locale == null) {\n                        Object selectedVariant = context.getAttribute(TemplateInstance.SELECTED_VARIANT);\n                        if (selectedVariant != null) {\n                            locale = ((Variant) selectedVariant).getLocale();\n                        }\n                        if (locale == null) {\n                            return defaultResolver.resolve(context);","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/qute/runtime/src/main/java/io/quarkus/qute/i18n/MessageBundles.java#L105-L141","documentation":"When setting up namespace resolvers, MessageBundles expects exactly one CDI bean per localized interface + locale. If container.select(...) finds multiple matching beans (ambiguous resolution), it throws IllegalStateException('Multiple beans found for localized interface ... and locale ...') instead of guessing.","triggerScenarios":"Two or more beans implementing the same bundle interface carry qualifiers that resolve to the same @Localized locale lookup — e.g. duplicate @Localized(\"de\") interfaces, or an implementation bean added alongside the generated bundle bean.","commonSituations":"Authoring the same localized bundle twice under different class names; a manual @Produces/@Alternative bean colliding with the generated one; copying bundle interfaces between packages creating duplicate @Localized values.","solutions":["Remove or rename the duplicate localized bundle so only one bean exists per interface+locale","Mark one bean @Alternative/@Priority if intentional overriding is needed","Ensure each @Localized annotation value is unique per bundle interface"],"exampleFix":"// before\ndelete AppMessagesDeCopy.java // duplicate @Localized(\"de\") interface\n// after\nkeep single @Localized(\"de\") AppMessagesDe interface","handlingStrategy":"validation","validationCode":"// Detect duplicates before startup: at most one @Localized bean per locale per bundle interface\nMap<String,Long> dupes = localizedBeans.stream()\n    .collect(Collectors.groupingBy(b -> b.getAnnotation(Localized.class).value(), Collectors.counting()));\ndupes.entrySet().stream().filter(e -> e.getValue() > 1).forEach(e -> {\n    throw new IllegalStateException(\"Duplicate @Localized(\" + e.getKey() + \") bundle\");\n});","typeGuard":null,"tryCatchPattern":"try {\n    startNamespaceResolvers();\n} catch (IllegalStateException e) {\n    if (e.getMessage().startsWith(\"Multiple beans found\")) {\n        throw new IllegalStateException(\"Remove the duplicate @Localized bundle for this locale\", e);\n    }\n    throw e;\n}","preventionTips":["Enforce one bundle interface per locale per bundle name in code review","Avoid manually producing beans that implement bundle interfaces","Use unique @Localized values; never duplicate the same locale string across classes","Mark intentional overrides with @Alternative and @Priority rather than adding a second bean"],"tags":["qute","i18n","cdi","ambiguous-resolution"],"backgroundTag":"ambiguous-bean-dependency","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}