{"record":{"id":"a8f007f9ecb445c2","repo":"quarkusio/quarkus","slug":"a-generic-type-is-not-allowed-here-try-creating-a","errorCode":null,"errorMessage":"A generic type is not allowed here; try creating a subclass with concrete type arguments instead: %s","messagePattern":"A generic type is not allowed here; try creating a subclass with concrete type arguments instead: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/builder/src/main/java/io/quarkus/builder/item/BuildItem.java","lineNumber":17,"sourceCode":"package io.quarkus.builder.item;\n\nimport java.lang.reflect.Modifier;\n\n/**\n * A build item which can be produced or consumed. Any item\n * which implements {@link AutoCloseable} will be automatically closed when the build\n * is completed, unless it is explicitly marked as a final build result in which case closure is\n * the responsibility of whomever invoked the build execution.\n * <p>\n * Resources should be fine-grained as possible, ideally describing only one aspect of the build process.\n */\npublic abstract class BuildItem {\n    BuildItem() {\n        final Class<? extends BuildItem> clazz = getClass();\n        if (clazz.getTypeParameters().length != 0) {\n            throw new IllegalArgumentException(\n                    \"A generic type is not allowed here; try creating a subclass with concrete type arguments instead: \"\n                            + getClass());\n        }\n        if (!Modifier.isFinal(clazz.getModifiers())) {\n            throw new IllegalArgumentException(\"Build item class must be leaf (final) types: \" + getClass());\n        }\n    }\n}\n","sourceCodeStart":1,"sourceCodeEnd":26,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/core/builder/src/main/java/io/quarkus/builder/item/BuildItem.java#L1-L26","documentation":"BuildItem's constructor enforces that every concrete build item is a non-generic, final class. It inspects getClass() at instantiation time and throws this IllegalArgumentException if the runtime class still declares type parameters. The Quarkus build system requires build items to be unique concrete types so they can be keyed in the dependency graph; a generic BuildItem<Multimap<String,String>> cannot be identified unambiguously.","triggerScenarios":"Declaring `class MyItem<T> extends BuildItem` and instantiating it (possibly via an anonymous or subclass form) instead of creating a concrete final subclass with fixed type arguments; instantiating a generic item directly with `new MyItem<Something>()`; using an anonymous class of a generic item that retains type parameters.","commonSituations":"Developers porting code that used generics for payload flexibility; refactoring where a generic base item was previously instantiated directly; anonymous subclassing `new BuildItem<Map<K,V>>(){}` patterns that keep type parameters at runtime.","solutions":["Create a concrete final subclass with fixed type arguments, e.g. `public final class StringMapItem extends BuildItem<Map<String,String>>` — wait, instead define `final class MyItem extends BuildItem` with fields, and use that.","Replace the generic type parameter with explicit fields on a final class (e.g. `final class LocaleMapBuildItem extends BuildItem { final Map<String,Locale> map; }`).","If instantiating an anonymous generic subclass, convert it to a named final class so getClass() has no type parameters.","Rebuild after changes — the check runs at construction, so any path constructing the generic class must be migrated."],"exampleFix":"// before\nclass MyItem<T> extends BuildItem {\n    final T payload;\n    MyItem(T payload) { this.payload = payload; }\n}\nnew MyItem<Map<String,String>>(map);\n\n// after\npublic final class MyMapItem extends BuildItem {\n    final Map<String,String> payload;\n    public MyMapItem(Map<String,String> payload) { this.payload = payload; }\n}\nnew MyMapItem(map);","handlingStrategy":"type-guard","validationCode":"static <T extends BuildItem> T validateNonGeneric(Class<? extends T> clazz) {\n    if (clazz.getTypeParameters().length != 0) {\n        throw new IllegalArgumentException(\n            clazz + \" is generic; define a concrete final subclass with fixed fields instead\");\n    }\n    return null; // validation-only helper; real instance is constructed after this passes\n}","typeGuard":"static boolean isConcreteBuildItem(Class<?> clazz) {\n    return BuildItem.class.isAssignableFrom(clazz)\n        && clazz.getTypeParameters().length == 0\n        && !clazz.isAnonymousClass();\n}","tryCatchPattern":"try {\n    BuildItem item = new MyMapItem(map);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().startsWith(\"A generic type is not allowed here\")) {\n        throw new IllegalStateException(\"Refactor \" + e.getMessage() + \" into a final concrete BuildItem subclass\", e);\n    }\n    throw e;\n}","preventionTips":["Never declare type parameters on BuildItem subclasses","Carry generic payloads in explicit typed fields of a concrete final item","Avoid anonymous subclassing of build items","Write an architecture/unit test asserting every BuildItem subclass is final and non-generic"],"tags":["quarkus","build-item","generics","api-misuse"],"backgroundTag":"generic-build-item-not-allowed","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"}