{"record":{"id":"51e59ee675b2aa1a","repo":"spring-projects/spring-framework","slug":"no-primary-or-single-unique-constructor-found-for","errorCode":null,"errorMessage":"No primary or single unique constructor found for {clazz}","messagePattern":"No primary or single unique constructor found for (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"spring-beans/src/main/java/org/springframework/beans/BeanUtils.java","lineNumber":265,"sourceCode":"\t\telse if (ctors.length == 0) {\n\t\t\t// No public constructors -> check non-public\n\t\t\tctors = clazz.getDeclaredConstructors();\n\t\t\tif (ctors.length == 1) {\n\t\t\t\t// A single non-public constructor, for example, from a non-public record type\n\t\t\t\treturn (Constructor<T>) ctors[0];\n\t\t\t}\n\t\t}\n\n\t\t// Several constructors -> let's try to take the default constructor\n\t\ttry {\n\t\t\treturn clazz.getDeclaredConstructor();\n\t\t}\n\t\tcatch (NoSuchMethodException ex) {\n\t\t\t// Giving up...\n\t\t}\n\n\t\t// No unique constructor at all\n\t\tthrow new IllegalStateException(\"No primary or single unique constructor found for \" + clazz);\n\t}\n\n\t/**\n\t * Return the primary constructor of the provided class. For Kotlin classes, this\n\t * returns the Java constructor corresponding to the Kotlin primary constructor\n\t * (as defined in the Kotlin specification). For Java records, this returns the\n\t * canonical constructor. Otherwise, this simply returns {@code null}.\n\t * @param clazz the class to check\n\t * @since 5.0\n\t * @see <a href=\"https://kotlinlang.org/docs/reference/classes.html#constructors\">Kotlin constructors</a>\n\t * @see <a href=\"https://docs.oracle.com/javase/specs/jls/se17/html/jls-8.html#jls-8.10.4\">Record constructor declarations</a>\n\t */\n\tpublic static <T> @Nullable Constructor<T> findPrimaryConstructor(Class<T> clazz) {\n\t\tAssert.notNull(clazz, \"Class must not be null\");\n\t\tif (KOTLIN_REFLECT_PRESENT && KotlinDetector.isKotlinType(clazz)) {\n\t\t\treturn KotlinDelegate.findPrimaryConstructor(clazz);\n\t\t}\n\t\tif (clazz.isRecord()) {","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/spring-projects/spring-framework/blob/69bf83ad716d0cfc4b0520a19b4d8b24c79d1538/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java#L247-L283","documentation":"Thrown as IllegalStateException (not a BeansException) by getResolvableConstructor at BeanUtils.java:265 when a class has multiple public constructors, no Kotlin primary constructor, is not a record, and has no no-arg default constructor either — i.e. there is no single unambiguous constructor Spring can pick. The algorithm in getResolvableConstructor exhausted primary-constructor, single-public, single-non-public, and default-constructor lookup.","triggerScenarios":"Calling getResolvableConstructor(clazz) (used by @ConfigurationProperties, constructor binding, data binding) on a class with two or more public constructors and no no-arg constructor. None of the disambiguation heuristics (single public, single non-public, default) apply, so resolution fails.","commonSituations":"@ConfigurationProperties class with overloaded constructors; constructor-binding DTOs with multiple explicit constructors; domain entities with several public constructors and no default; Spring Boot 3 / Spring 6 stricter constructor binding that requires an unambiguous constructor.","solutions":["Annotate the intended constructor with @ConstructorProperties or make it the only public constructor.","Add a no-arg default constructor so the fallback in getResolvableConstructor succeeds.","Reduce to a single public constructor (make others non-public).","Use an explicit @Bean factory method or explicit Constructor argument instead of relying on auto-resolution."],"exampleFix":"// before: ambiguous\npublic class Props {\n    public Props(String a) {}\n    public Props(String a, int b) {}\n}\n\n// after\npublic class Props {\n    public Props() {}\n    public Props(String a, int b) { ... }\n}","handlingStrategy":"validation","validationCode":"Constructor<?> c = BeanUtils.findPrimaryConstructor(clazz);\nif (c == null) {\n    Constructor<?>[] publics = clazz.getConstructors();\n    if (publics.length != 1) {\n        // expect multiple -> ensure a no-arg ctor exists or annotate one\n        try { clazz.getDeclaredConstructor(); }\n        catch (NoSuchMethodException e) { /* will fail */ }\n    }\n}","typeGuard":"static boolean hasResolvableConstructor(Class<?> c) {\n    if (BeanUtils.findPrimaryConstructor(c) != null) return true;\n    if (c.getConstructors().length == 1) return true;\n    try { c.getDeclaredConstructor(); return true; }\n    catch (NoSuchMethodException e) { return false; }\n}","tryCatchPattern":"try {\n    BeanUtils.getResolvableConstructor(clazz);\n} catch (IllegalStateException ex) {\n    // ambiguous -> supply explicit constructor to the binder/factory\n    Constructor<?> chosen = clazz.getDeclaredConstructor(String.class, int.class);\n}","preventionTips":["Give @ConfigurationProperties/value classes a single public constructor or a no-arg constructor.","Use @ConstructorProperties to declare the canonical constructor for binding.","Make overloaded constructors non-public so a single public one is unambiguous.","Validate constructor structure in unit tests for binding targets."],"tags":["spring-beans","beanutils","constructor-binding","configuration-properties","ambiguous","reflection"],"backgroundTag":null,"analyzedSha":"69bf83ad716d0cfc4b0520a19b4d8b24c79d1538","analyzedAt":"2026-08-09T15:32:58.770Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}