{"record":{"id":"0686e07136fb959e","repo":"quarkusio/quarkus","slug":"multiple-fallback-found-for-a-base-codestart-of-ty","errorCode":null,"errorMessage":"Multiple fallback found for a base codestart of type: '\" + a.getSpec().getType() + \"' that should be unique. Only one of '\" + a.getSpec().getName() + \"' and '\" + b.getSpec().getName() + \"' should be a fallback","messagePattern":"Multiple fallback found for a base codestart of type: '\" \\+ a\\.getSpec\\(\\)\\.getType\\(\\) \\+ \"' that should be unique\\. Only one of '\" \\+ a\\.getSpec\\(\\)\\.getName\\(\\) \\+ \"' and '\" \\+ b\\.getSpec\\(\\)\\.getName\\(\\) \\+ \"' should be a fallback","errorType":"exception","errorClass":"CodestartStructureException","httpStatus":null,"severity":"error","filePath":"independent-projects/tools/codestarts/src/main/java/io/quarkus/devtools/codestarts/core/CodestartCatalogs.java","lineNumber":62,"sourceCode":"        return codestarts.stream().filter(c -> {\n            if (!c.implementsLanguage(languageName)) {\n                projectInput.log().warn(\n                        c.getName() + \" codestart will not be applied (doesn't implement language '\" + languageName\n                                + \"' yet)\");\n                return false;\n            }\n            return true;\n        }).collect(Collectors.toList());\n    }\n\n    static Collection<Codestart> getBaseSelection(Collection<Codestart> codestarts, Set<String> selection) {\n        return codestarts.stream()\n                .filter(c -> c.getSpec().getType().isBase())\n                .filter(c -> c.getSpec().isFallback() || c.isSelected(selection))\n                .collect(Collectors.toMap(c -> c.getSpec().getType(), c -> c, (a, b) -> {\n                    // When there is multiple matches for one key, one should be selected and the other a fallback.\n                    if (a.getSpec().isFallback() && b.getSpec().isFallback()) {\n                        throw new CodestartStructureException(\n                                \"Multiple fallback found for a base codestart of type: '\" + a.getSpec().getType()\n                                        + \"' that should be unique. Only one of '\" + a.getSpec().getName() + \"' and '\"\n                                        + b.getSpec().getName() + \"' should be a fallback\");\n                    }\n                    if (!a.getSpec().isFallback() && !b.getSpec().isFallback()) {\n                        throw new CodestartException(\n                                \"Multiple selection for base codestart of type: '\" + a.getSpec().getType()\n                                        + \"' that should be unique. Only one of '\" + a.getSpec().getName() + \"' and '\"\n                                        + b.getSpec().getName() + \"' should be selected at once.\");\n                    }\n                    // The selected is picked.\n                    return !a.getSpec().isFallback() ? a : b;\n                })).values();\n    }\n\n    static Collection<Codestart> getExtraSelection(Collection<Codestart> codestarts, Set<String> selection) {\n        return codestarts.stream()\n                .filter(c -> !c.getSpec().getType().isBase())","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/tools/codestarts/src/main/java/io/quarkus/devtools/codestarts/core/CodestartCatalogs.java#L44-L80","documentation":"CodestartCatalogs.getBaseSelection() throws CodestartStructureException when a duplicate-resolution for a base codestart type finds two candidates that are BOTH marked as fallback. For each base type, exactly one selected codestart plus at most one fallback is allowed; two fallbacks mean a broken catalog structure.","triggerScenarios":"Selecting codestarts where two different codestarts of the same base type (e.g. two 'config' base codestarts) both have fallback: true, causing the Collectors.toMap merge function to detect the conflict.","commonSituations":"Registering a custom codestart that duplicates an existing fallback base codestart (same type) in another catalog; copy-pasting codestart definitions without clearing the fallback flag.","solutions":["Set fallback: false on one of the two codestarts of the duplicated base type.","Remove the redundant custom codestart that duplicates the built-in fallback.","Give the codestarts distinct types if they are meant to coexist rather than be fallback alternatives."],"exampleFix":"# before (two codestarts)\nname: custom-config\ntype: config\nfallback: true\n# after\nname: custom-config\ntype: config\nfallback: false","handlingStrategy":"validation","validationCode":"// before registration: ensure only one fallback per base type\nMap<String, Long> fallbacks = codestarts.stream()\n    .filter(c -> c.getSpec().getType().isBase() && c.getSpec().isFallback())\n    .collect(Collectors.groupingBy(c -> c.getSpec().getType().name(), Collectors.counting()));\nif (fallbacks.values().stream().anyMatch(n -> n > 1)) throw new IllegalStateException(\"Duplicate fallback base codestarts\");","typeGuard":null,"tryCatchPattern":"try {\n    var selected = CodestartCatalogs.select(catalogs, selection);\n} catch (CodestartStructureException e) {\n    if (e.getMessage().contains(\"Multiple fallback\")) {\n        logger.error(\"Duplicate fallback codestarts for one base type — fix spec files\");\n    }\n    throw e;\n}","preventionTips":["Keep exactly one fallback per base codestart type across all catalogs.","Set fallback: false on custom codestarts that mirror built-ins.","Audit extension codestart metadata for type collisions."],"tags":["codestart","catalog","duplicate","configuration"],"backgroundTag":"duplicate-codestart-fallback","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"}