{"record":{"id":"623c377fcaf07182","repo":"quarkusio/quarkus","slug":"message-bundle-interface-name-conflict-s-is-u","errorCode":null,"errorMessage":"Message bundle interface name conflict - [%s] is used for both [%s] and [%s]","messagePattern":"Message bundle interface name conflict - \\[(.+?)\\] is used for both \\[(.+?)\\] and \\[(.+?)\\]","errorType":"exception","errorClass":"MessageBundleException","httpStatus":null,"severity":"error","filePath":"extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/MessageBundleProcessor.java","lineNumber":187,"sourceCode":"                                    names.add(enclosingClass.simpleName());\n                                    enclosingName = enclosingClass.nestingType() == NestingType.TOP_LEVEL ? null\n                                            : enclosingClass.enclosingClass();\n                                }\n                            }\n                            Collections.reverse(names);\n                            name = String.join(\"_\", names);\n                        }\n                        LOG.debugf(\"Message bundle %s: name defaulted to %s\", bundleClass, name);\n                    }\n                    if (!Namespaces.isValidNamespace(name)) {\n                        throw new MessageBundleException(\n                                String.format(\n                                        \"Message bundle name [%s] declared on %s must be a valid namespace - the value can only consist of alphanumeric characters and underscores\",\n                                        name, bundleClass));\n                    }\n\n                    if (found.containsKey(name)) {\n                        throw new MessageBundleException(\n                                String.format(\"Message bundle interface name conflict - [%s] is used for both [%s] and [%s]\",\n                                        name, bundleClass, found.get(name)));\n                    }\n                    found.put(name, bundleClass);\n\n                    // Find localizations for each interface\n                    String defaultLocale = getDefaultLocale(bundleAnnotation, locales);\n                    List<ClassInfo> localized = new ArrayList<>();\n                    for (ClassInfo implementor : index.getKnownDirectSubinterfaces(bundleClass.name())) {\n                        localized.add(implementor);\n                    }\n                    Map<String, ClassInfo> localeToInterface = new HashMap<>();\n                    for (ClassInfo localizedInterface : localized) {\n                        String locale = localizedInterface.declaredAnnotation(Names.LOCALIZED).value().asString();\n                        if (defaultLocale.equals(locale)) {\n                            throw new MessageBundleException(\n                                    String.format(\n                                            \"Locale of [%s] conflicts with the locale [%s] of the default message bundle [%s]\",","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/qute/deployment/src/main/java/io/quarkus/qute/deployment/MessageBundleProcessor.java#L169-L205","documentation":"MessageBundleException thrown at build time when two different interfaces annotated with @MessageBundle resolve to the same bundle name. Each bundle name is a unique template namespace, so duplicates would make bean registration and message resolution ambiguous. The build fails naming both conflicting interfaces.","triggerScenarios":"Two interfaces annotated @MessageBundle with the same explicit value (e.g. both @MessageBundle(\"msg\")); or a top-level bundle interface plus a nested one whose defaulted name collides (a nested interface named Msg with default name 'msg' collides with the default 'msg' of a top-level bundle).","commonSituations":"Merging modules or refactoring that moved a bundle interface and left a duplicate behind; inheriting a library bundle with the default name 'msg' while defining your own top-level @MessageBundle interface; copy-pasting a bundle interface into a nested class without changing the name.","solutions":["Give one of the interfaces a distinct @MessageBundle name, e.g. @MessageBundle(\"admin_msg\").","If a dependency provides a bundle with the default name, set an explicit unique name on your own bundle interface.","Delete or consolidate the duplicate bundle interface and update template usages accordingly."],"exampleFix":"// before (conflict: both resolve to \"msg\")\n@MessageBundle public interface Msg { ... }\npublic class Component { @MessageBundle public interface Msg { ... } }\n\n// after\n@MessageBundle public interface Msg { ... }\npublic class Component { @MessageBundle(\"component_msg\") public interface Msg { ... } }","handlingStrategy":"validation","validationCode":"// before build, detect duplicate @MessageBundle names across the project:\n// grep -rE '@MessageBundle(\\(\"[^\"]+\"\\))?' --include='*.java' src/ | sort | uniq -d","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Give every bundle interface a unique, explicit name except one canonical top-level default bundle.","Never name a nested bundle interface 'Msg' if a top-level default bundle exists (derived name collides with 'msg').","Keep bundles in one well-known package to avoid accidental duplicates across modules.","Run a full build (not just IDE compile) in CI so the Qute build step catches conflicts."],"tags":["quarkus","qute","message-bundle","name-conflict","build-time"],"backgroundTag":"duplicate-name-conflict","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"}