{"record":{"id":"bc3ce91cb0d18b4e","repo":"spring-projects/spring-framework","slug":"no-unique-bean-definition","errorCode":null,"errorMessage":"No unique bean definition","messagePattern":"No unique bean definition","errorType":"exception","errorClass":"NoUniqueBeanDefinitionException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java","lineNumber":192,"sourceCode":"\tpublic boolean isEager() {\n\t\treturn this.eager;\n\t}\n\n\t/**\n\t * Resolve the specified not-unique scenario: by default,\n\t * throwing a {@link NoUniqueBeanDefinitionException}.\n\t * <p>Subclasses may override this to select one of the instances or\n\t * to opt out with no result at all through returning {@code null}.\n\t * @param type the requested bean type\n\t * @param matchingBeans a map of bean names and corresponding bean\n\t * instances which have been pre-selected for the given type\n\t * (qualifiers etc already applied)\n\t * @return a bean instance to proceed with, or {@code null} for none\n\t * @throws BeansException in case of the not-unique scenario being fatal\n\t * @since 5.1\n\t */\n\tpublic @Nullable Object resolveNotUnique(ResolvableType type, Map<String, Object> matchingBeans) throws BeansException {\n\t\tthrow new NoUniqueBeanDefinitionException(type, matchingBeans.keySet());\n\t}\n\n\t/**\n\t * Resolve a shortcut for this dependency against the given factory, for example\n\t * taking some pre-resolved information into account.\n\t * <p>The resolution algorithm will first attempt to resolve a shortcut through this\n\t * method before going into the regular type matching algorithm across all beans.\n\t * Subclasses may override this method to improve resolution performance based on\n\t * pre-cached information while still receiving {@link InjectionPoint} exposure etc.\n\t * @param beanFactory the associated factory\n\t * @return the shortcut result if any, or {@code null} if none\n\t * @throws BeansException if the shortcut could not be obtained\n\t * @since 4.3.1\n\t */\n\tpublic @Nullable Object resolveShortcut(BeanFactory beanFactory) throws BeansException {\n\t\treturn null;\n\t}\n","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-beans/src/main/java/org/springframework/beans/factory/config/DependencyDescriptor.java#L174-L210","documentation":"Thrown as a NoUniqueBeanDefinitionException by DependencyDescriptor.resolveNotUnique when multiple beans of the requested type survive qualifier filtering and none is marked @Primary, no @Qualifier pins one down, and the injection is not a collection/Optional. It is the default resolution for the not-unique scenario, designed to be overridden by subclasses that want to pick a winner or opt out.","triggerScenarios":"DependencyDescriptor.resolveNotUnique is called by the resolver when more than one candidate bean matches the dependency type (after qualifiers). The default implementation throws NoUniqueBeanDefinitionException with the candidate bean names; subclasses (e.g. ShortcutDependencyDescriptor, parameterized-collection descriptors) override it to choose differently.","commonSituations":"Two DataSource/RestTemplate/EntityManager beans with no @Primary; multiple @Configuration classes each defining a bean of the same type; autowiring by type where a profile brings in extra candidates; forgotten @Qualifier on an injection point; previously-unique bean now duplicated after adding a starter.","solutions":["Mark exactly one candidate @Primary so the type-resolved injection has a single winner.","Add @Qualifier('beanName') on the injection point (field, constructor param, setter) to select a candidate.","Reduce the candidates: remove one of the bean definitions, or guard them with @Profile so only one is active.","Inject a List<T>/Map<String,T>/ObjectProvider<T> when you genuinely want all candidates.","If you wrote a custom DependencyDescriptor, override resolveNotUnique to pick a candidate or return null instead of throwing."],"exampleFix":"// before: two DataSource beans, ambiguous autowiring\n@Bean DataSource primary() { ... }\n@Bean DataSource replica() { ... }\n@Autowired DataSource ds; // NoUniqueBeanDefinitionException\n\n// after: disambiguate with @Primary\n@Bean @Primary DataSource primary() { ... }\n@Bean DataSource replica() { ... }","handlingStrategy":"validation","validationCode":"String[] names = beanFactory.getBeanNamesForType(requiredType);\nif (names.length > 1 && beanFactory.getBean(names[0], requiredType) /* no primary */) {\n    throw new NoUniqueBeanDefinitionException(requiredType, java.util.Arrays.asList(names));\n}","typeGuard":"// True when exactly one candidate is resolvable for the type\nboolean unique = beanFactory.getBeanNamesForType(type).length == 1;","tryCatchPattern":"try {\n    return beanFactory.getBean(type);\n} catch (NoUniqueBeanDefinitionException ex) {\n    // pick by qualifier, @Primary, or fall back to a default\n    return beanFactory.getBean(qualifier, type);\n}","preventionTips":["Mark a single candidate @Primary when multiple of a type exist.","Add @Qualifier on injection points to disambiguate.","Use @Profile to ensure only one candidate is active per environment.","Inject List<T>/ObjectProvider<T> when all candidates are genuinely wanted."],"tags":["spring","dependency-injection","ambiguous-bean","autowiring","qualifier"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}