{"record":{"id":"1297677af53d687a","repo":"gradle/gradle","slug":"s-has-no-constructor-that-is-annotated-with-inje","errorCode":null,"errorMessage":"%s has no constructor that is annotated with @Inject (javax.inject.Inject) for dependency injection.","messagePattern":"(.+?) has no constructor that is annotated with @Inject \\(javax\\.inject\\.Inject\\) for dependency injection\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"platforms/core-configuration/model-core/src/main/java/org/gradle/internal/instantiation/generator/InjectUtil.java","lineNumber":76,"sourceCode":"                formatter.append(\" should be \");\n                appendAnnotatedWithInject(formatter);\n                throw new IllegalArgumentException(formatter.toString());\n            }\n        }\n\n        List<ClassGenerator.GeneratedConstructor<T>> injectConstructors = new ArrayList<ClassGenerator.GeneratedConstructor<T>>();\n        for (ClassGenerator.GeneratedConstructor<T> constructor : constructors) {\n            if (constructor.getAnnotation(Inject.class) != null) {\n                injectConstructors.add(constructor);\n            }\n        }\n\n        if (injectConstructors.isEmpty()) {\n            TreeFormatter formatter = new TreeFormatter();\n            formatter.node(reportAs);\n            formatter.append(\" has no constructor that is \");\n            appendAnnotatedWithInject(formatter);\n            throw new IllegalArgumentException(formatter.toString());\n        }\n        if (injectConstructors.size() > 1) {\n            TreeFormatter formatter = new TreeFormatter();\n            formatter.node(reportAs);\n            formatter.append(\" has multiple constructors that are \");\n            appendAnnotatedWithInject(formatter);\n            throw new IllegalArgumentException(formatter.toString());\n        }\n\n        return injectConstructors.get(0);\n    }\n\n    private static void appendAnnotatedWithInject(TreeFormatter formatter) {\n        formatter.append(\"annotated with @Inject (\");\n        formatter.append(Inject.class.getName());\n        formatter.append(\") for dependency injection.\");\n    }\n","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/gradle/gradle/blob/534f27719b66953f95cc907aae7f2c1b12f5482d/platforms/core-configuration/model-core/src/main/java/org/gradle/internal/instantiation/generator/InjectUtil.java#L58-L94","documentation":"When a type declares multiple constructors, InjectUtil requires exactly one to be annotated with @Inject. If none carries the annotation, constructor selection is impossible and Gradle throws IllegalArgumentException naming the type before instantiation proceeds.","triggerScenarios":"A type with overloaded constructors, for example MyType(), MyType(String), MyType(String, int), with no @Inject on any of them, instantiated through the JSR-330 selector.","commonSituations":"Backwards-compatible constructors accumulated across releases; Lombok-generated constructors plus a hand-written one; Groovy classes where @Inject was placed on the class instead of a constructor.","solutions":["Designate one canonical constructor and annotate it with @Inject.","Delete redundant constructors if they all populate the same fields.","In Groovy, target the constructor explicitly: @Inject MyType(String name) { }."],"exampleFix":"// before\nMyType() {}\nMyType(String name) { this.name = name; }\n// after\nMyType() {}\n@Inject\nMyType(String name) { this.name = name; }","handlingStrategy":"validation","validationCode":"long injectCount = Arrays.stream(type.getDeclaredConstructors())\n    .filter(c -> c.isAnnotationPresent(javax.inject.Inject.class)).count();\nif (type.getDeclaredConstructors().length > 1 && injectCount != 1) {\n    throw new IllegalStateException(\"type needs exactly one @Inject constructor: \" + type.getName());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep exactly one designated injection constructor per type.","In Groovy, place @Inject directly before the constructor declaration, not on the class."],"tags":["gradle","dependency-injection","inject-annotation","constructor-selection"],"backgroundTag":"missing-inject-annotation","analyzedSha":"534f27719b66953f95cc907aae7f2c1b12f5482d","analyzedAt":"2026-08-22T08:09:12.375Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}