quarkusio/quarkus · error · CodestartStructureException
Multiple fallback found for a base codestart of type: '" + a
Error message
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
What it means
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.
Source
Thrown at independent-projects/tools/codestarts/src/main/java/io/quarkus/devtools/codestarts/core/CodestartCatalogs.java:62
return codestarts.stream().filter(c -> {
if (!c.implementsLanguage(languageName)) {
projectInput.log().warn(
c.getName() + " codestart will not be applied (doesn't implement language '" + languageName
+ "' yet)");
return false;
}
return true;
}).collect(Collectors.toList());
}
static Collection<Codestart> getBaseSelection(Collection<Codestart> codestarts, Set<String> selection) {
return codestarts.stream()
.filter(c -> c.getSpec().getType().isBase())
.filter(c -> c.getSpec().isFallback() || c.isSelected(selection))
.collect(Collectors.toMap(c -> c.getSpec().getType(), c -> c, (a, b) -> {
// When there is multiple matches for one key, one should be selected and the other a fallback.
if (a.getSpec().isFallback() && b.getSpec().isFallback()) {
throw new CodestartStructureException(
"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");
}
if (!a.getSpec().isFallback() && !b.getSpec().isFallback()) {
throw new CodestartException(
"Multiple selection for base codestart of type: '" + a.getSpec().getType()
+ "' that should be unique. Only one of '" + a.getSpec().getName() + "' and '"
+ b.getSpec().getName() + "' should be selected at once.");
}
// The selected is picked.
return !a.getSpec().isFallback() ? a : b;
})).values();
}
static Collection<Codestart> getExtraSelection(Collection<Codestart> codestarts, Set<String> selection) {
return codestarts.stream()
.filter(c -> !c.getSpec().getType().isBase())View on GitHub (pinned to e1c734241f)
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.
Example fix
# before (two codestarts) name: custom-config type: config fallback: true # after name: custom-config type: config fallback: false
Defensive patterns
Strategy: validation
Validate before calling
// before registration: ensure only one fallback per base type
Map<String, Long> fallbacks = codestarts.stream()
.filter(c -> c.getSpec().getType().isBase() && c.getSpec().isFallback())
.collect(Collectors.groupingBy(c -> c.getSpec().getType().name(), Collectors.counting()));
if (fallbacks.values().stream().anyMatch(n -> n > 1)) throw new IllegalStateException("Duplicate fallback base codestarts"); Try / catch
try {
var selected = CodestartCatalogs.select(catalogs, selection);
} catch (CodestartStructureException e) {
if (e.getMessage().contains("Multiple fallback")) {
logger.error("Duplicate fallback codestarts for one base type — fix spec files");
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Multiple selection for base codestart of type: '" + a.getSpe
- ConflictStrategyHandler named '" + entry.getValue() + "' not
- can't be used as '*' file strategy
- Failed to load application configuration
- Failed to initialize application configuration
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/0686e07136fb959e.
Report an issue: GitHub.