{"record":{"id":"297a193415706453","repo":"quarkusio/quarkus","slug":"unable-to-scan-config-group-configgroup","errorCode":null,"errorMessage":"Unable to scan config group: ${configGroup}","messagePattern":"Unable to scan config group: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/scanner/ConfigAnnotationScanner.java","lineNumber":89,"sourceCode":"        configMappingWithoutConfigRootListeners.add(new JavadocConfigMappingListener(config, utils, configCollector));\n\n        this.configRootListeners = Collections.unmodifiableList(configRootListeners);\n        this.configMappingWithoutConfigRootListeners = Collections.unmodifiableList(configMappingWithoutConfigRootListeners);\n    }\n\n    public void scanConfigGroups(RoundEnvironment roundEnv, TypeElement annotation) {\n        for (TypeElement configGroup : ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(annotation))) {\n            if (isConfigGroupAlreadyHandled(configGroup)) {\n                continue;\n            }\n\n            debug(\"Detected annotated config group: \" + configGroup, configGroup);\n\n            try {\n                DiscoveryConfigGroup discoveryConfigGroup = applyRootListeners(l -> l.onConfigGroup(configGroup));\n                scanElement(configRootListeners, discoveryConfigGroup, configGroup);\n            } catch (Exception e) {\n                throw new IllegalStateException(\"Unable to scan config group: \" + configGroup, e);\n            }\n        }\n    }\n\n    public void scanConfigRoots(RoundEnvironment roundEnv, TypeElement annotation) {\n        for (TypeElement configRoot : typesIn(roundEnv.getElementsAnnotatedWith(annotation))) {\n            checkConfigRootAnnotationConsistency(configRoot);\n\n            final PackageElement pkg = utils.element().getPackageOf(configRoot);\n            if (pkg == null) {\n                utils.processingEnv().getMessager().printMessage(Diagnostic.Kind.ERROR,\n                        \"Element \" + configRoot + \" has no enclosing package\");\n                continue;\n            }\n\n            if (isConfigRootAlreadyHandled(configRoot)) {\n                continue;\n            }","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/core/processor/src/main/java/io/quarkus/annotation/processor/documentation/config/scanner/ConfigAnnotationScanner.java#L71-L107","documentation":"The config documentation annotation processor failed while scanning an annotated config group class (@ConfigMapping with nested group semantics). Listeners run during scanConfigGroups to discover the group's properties; any exception they throw is wrapped in this IllegalStateException naming the config group type.","triggerScenarios":"Compiling code containing a class annotated as a config group where listener processing fails: malformed/unsupported member types, missing generics info, unresolvable nested types, or a listener bug triggered by an unusual mapping annotation layout.","commonSituations":"A config group with an exotic field type (e.g. raw Optional of a non-convertible type, unregistered enum, recursive group reference); annotation processing running against partially compiled sources after an incomplete build; a Quarkus regression triggered by a specific mapping shape.","solutions":["Read the wrapped 'Caused by' exception — it pinpoints the actual failure (unregistered enum, unresolvable type, etc.).","Fix the named config group: check field types are supported config types and enums are properly registered/annotated.","Clean and rebuild so the processor sees fully resolvable sources.","Register any custom types the scanner must resolve (e.g. ensure enums used in the group are discoverable).","If the wrapped error is a Quarkus processor bug, minimize the group and report it upstream."],"exampleFix":"// before: unregistered/odd type in the group\npublic class MyAppGroup {\n    public SomeUnregisteredEnum mode; // scan fails\n}\n\n// after: use a supported, registered type\npublic class MyAppGroup {\n    public Mode mode; // enum registered via @Enumerated/config docs scanning\n    public enum Mode { FAST, SLOW }\n}","handlingStrategy":"validation","validationCode":"// pre-check the group before compiling docs\nfor (var m : configGroupClass.getDeclaredFields()) {\n    if (!isSupportedConfigType(m.getType()))\n        throw new IllegalStateException(\"Unsupported group member type: \" + m);\n}","typeGuard":"static boolean isScannableGroup(Class<?> g) {\n    return Arrays.stream(g.getDeclaredFields())\n        .allMatch(f -> f.getType().isPrimitive()\n            || CONVERTIBLE_TYPES.contains(f.getType())\n            || f.getType().isEnum()\n            || isConfigGroup(f.getType()));\n}","tryCatchPattern":"try {\n    scanner.scanConfigGroups(roundEnv, annotation);\n} catch (IllegalStateException e) {\n    if (e.getMessage().startsWith(\"Unable to scan config group:\")) {\n        log.error(\"Fix the config group named in the message; see Caused by for root cause\");\n    }\n    throw e; // build must fail\n}","preventionTips":["Use only supported config types (primitives, String, Optional, collections of convertibles, nested groups, enums) in groups.","Avoid recursive group references.","Keep Quarkus versions aligned across modules.","Always read the wrapped 'Caused by' to find the real offending member."],"tags":["quarkus","annotation-processing","config-mapping","build","scanner"],"backgroundTag":"annotation-scanning-failed","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"}