{"record":{"id":"73232bb666bc1347","repo":"quarkusio/quarkus","slug":"multiple-instances-of-1-s-were-found-for-hibernat-73232b","errorCode":null,"errorMessage":"Multiple instances of %1$s were found for Hibernate Search Standalone. At most one instance can be assigned. Instances found: %2$s","messagePattern":"Multiple instances of %1\\$s were found for Hibernate Search Standalone\\. At most one instance can be assigned\\. Instances found: %2\\$s","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/hibernate-search-standalone-elasticsearch/runtime/src/main/java/io/quarkus/hibernate/search/standalone/elasticsearch/runtime/bean/HibernateSearchBeanUtil.java","lineNumber":44,"sourceCode":"\n    private static <T> Optional<BeanReference<T>> singleExtensionBeanReferenceFor(Class<T> beanType,\n            String backendName, String indexName) {\n        InjectableInstance<T> instance = extensionInstanceFor(beanType, backendName, indexName);\n        if (instance.isAmbiguous()) {\n            List<String> ambiguousClassNames = instance.handlesStream().map(h -> h.getBean().getBeanClass().getCanonicalName())\n                    .toList();\n            if (indexName != null) {\n                throw new IllegalStateException(String.format(Locale.ROOT,\n                        \"Multiple instances of %1$s were found for Hibernate Search Standalone index %2$s.\"\n                                + \" At most one instance can be assigned to each index. Instances found: %3$s\",\n                        beanType.getSimpleName(), indexName, ambiguousClassNames));\n            } else if (backendName != null) {\n                throw new IllegalStateException(String.format(Locale.ROOT,\n                        \"Multiple instances of %1$s were found for Hibernate Search Standalone backend %2$s.\"\n                                + \" At most one instance can be assigned to each backend. Instances found: %3$s\",\n                        beanType.getSimpleName(), backendName, ambiguousClassNames));\n            } else {\n                throw new IllegalStateException(String.format(Locale.ROOT,\n                        \"Multiple instances of %1$s were found for Hibernate Search Standalone.\"\n                                + \" At most one instance can be assigned. Instances found: %2$s\",\n                        beanType.getSimpleName(), ambiguousClassNames));\n            }\n        }\n        return instance.isResolvable() ? Optional.of(new ArcBeanReference<>(instance.getHandle().getBean())) : Optional.empty();\n    }\n\n    public static <T> Optional<List<BeanReference<T>>> multiExtensionBeanReferencesFor(Optional<List<String>> override,\n            Class<T> beanType,\n            String backendName, String indexName) {\n        return override.map(strings -> strings.stream()\n                .map(string -> BeanReference.parse(beanType, string))\n                .collect(Collectors.toList()))\n                .or(() -> multiExtensionBeanReferencesFor(beanType, backendName, indexName));\n    }\n\n    private static <T> Optional<List<BeanReference<T>>> multiExtensionBeanReferencesFor(Class<T> beanType,","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/hibernate-search-standalone-elasticsearch/runtime/src/main/java/io/quarkus/hibernate/search/standalone/elasticsearch/runtime/bean/HibernateSearchBeanUtil.java#L26-L62","documentation":"Global-scope variant of the ambiguity check: when neither an index nor backend name applies, singleExtensionBeanReferenceFor() requires exactly one bean of beanType in the whole Hibernate Search Standalone context. If multiple globally-qualified beans of that type exist, it throws IllegalStateException enumerating them.","triggerScenarios":"Two or more beans of beanType carry @HibernateSearchExtension without backend/index targeting (global scope), so the plain lookup is ambiguous and instance.isAmbiguous() fires.","commonSituations":"Registering two global customizations of the same role (e.g. two mass-indexing observers or two mapper beans) both annotated without scope qualifiers; leaving a test/alternative bean (@Alternative not active or both discovered) in the archive; adding an extension default bean plus your own global bean.","solutions":["Remove one of the globally-scoped beans listed in the 'Instances found' message.","Target each bean to a specific backend or index via @HibernateSearchExtension(backend=.../index=...) so the global lookup resolves uniquely.","Mark the undesired bean as @Vetoed or remove its bean-defining annotation so ArC ignores it.","If intentional replacement is wanted, use @Alternative + @Priority instead of registering two beans side by side."],"exampleFix":"// before: two global beans of the same type\n@HibernateSearchExtension\n@ApplicationScoped public class ObserverA implements MassIndexingObserver { ... }\n@HibernateSearchExtension\n@ApplicationScoped public class ObserverB implements MassIndexingObserver { ... }\n\n// after: keep one, or target the other\n@HibernateSearchExtension\n@ApplicationScoped public class ObserverA implements MassIndexingObserver { ... }\n// ObserverB deleted (or annotated with @Vetoed)","handlingStrategy":"validation","validationCode":"// Global-scope ambiguity check\nInjectableInstance<MyType> i = Arc.container().select(MyType.class, hibernateSearchExtensionQualifier);\nif (i.isAmbiguous()) {\n    throw new IllegalStateException(\"Multiple global Hibernate Search beans of \" + MyType.class);\n}","typeGuard":"public static <T> boolean hasSingleGlobalBean(Class<T> type, Annotation... qualifiers) {\n    var instance = Arc.container().select(type, qualifiers);\n    return instance.isResolvable() && !instance.isAmbiguous();\n}","tryCatchPattern":"try {\n    Optional<BeanReference<T>> ref = HibernateSearchBeanUtil.singleExtensionBeanReferenceFor(beanType, null, null);\n} catch (IllegalStateException e) {\n    log.errorf(\"Multiple global Hibernate Search Standalone beans found — keep one or add backend/index qualifiers: %s\", e.getMessage(), e);\n}","preventionTips":["Register at most one unqualified (global) bean per extension role.","Use @Alternative with @Priority for intentional replacement instead of parallel beans.","Annotate test-only beans with @Vetoed so they never enter production resolution.","When the extension also provides a default bean, target yours to a backend/index or disable the default via config."],"tags":["cdi","quarkus","hibernate-search","ambiguous-bean"],"backgroundTag":"ambiguous-cdi-bean","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"}