apache/maven · error · ComponentConfigurationException
Implementation hint '{}' is ambiguous for sealed type {}: {}
Error message
Implementation hint '{}' is ambiguous for sealed type {}: {} What it means
The implementation hint in configuration matches MORE THAN ONE permitted subclass of a sealed type, so the converter cannot pick one deterministically. Matching runs against FQN, canonical name, and simple name; when matches.size() > 1 the error lists all matching classes sorted by name so you can disambiguate.
Source
Thrown at impl/maven-core/src/main/java/org/apache/maven/configuration/internal/EnhancedConfigurationConverter.java:157
if (implementation.equals(permittedSubclass.getName())
|| implementation.equals(permittedSubclass.getCanonicalName())
|| implementation.equals(permittedSubclass.getSimpleName())) {
matches.add(permittedSubclass);
}
}
if (matches.size() == 1) {
return matches.get(0);
}
if (matches.isEmpty()) {
throw new ComponentConfigurationException(
configuration,
"Cannot find permitted subclass '" + implementation + "' for sealed type " + type.getName(),
cause);
}
matches.sort(Comparator.comparing(Class::getName));
throw new ComponentConfigurationException(
configuration,
"Implementation hint '" + implementation + "' is ambiguous for sealed type " + type.getName() + ": "
+ matches.stream().map(Class::getName).toList(),
cause);
}
public void processConfiguration(
final ConverterLookup lookup,
final Object bean,
final ClassLoader loader,
final PlexusConfiguration configuration,
final ExpressionEvaluator evaluator,
final ConfigurationListener listener)
throws ComponentConfigurationException {
final EnhancedCompositeBeanHelper helper = new EnhancedCompositeBeanHelper(lookup, loader, evaluator, listener);
for (int i = 0, size = configuration.getChildCount(); i < size; i++) {
final PlexusConfiguration element = configuration.getChild(i);
final String propertyName = fromXML(element.getName());View on GitHub (pinned to e4093d4e12)
Solutions
- Replace the simple name with the fully qualified class name of the implementation you want
- Pick the exact class from the match list printed in the error message itself
Example fix
<!-- before: ambiguous simple name --> <param implementation="Default"/> <!-- after: unique fully qualified name --> <param implementation="org.example.api.sealed.FileHandler"/>
Defensive patterns
Strategy: validation
Validate before calling
// Reject ambiguous hints before configuration is applied
List<Class<?>> matches = Arrays.stream(sealed.getPermittedSubclasses())
.filter(c -> hint.equals(c.getName()) || hint.equals(c.getCanonicalName()) || hint.equals(c.getSimpleName()))
.toList();
if (matches.size() != 1) {
throw new IllegalArgumentException(
matches.isEmpty() ? "no permitted subclass matches '" + hint + "'"
: "ambiguous hint '" + hint + "': " + matches);
} Prevention
- Never rely on simple class names in implementation attributes
- Lint configuration files to require FQNs whenever an implementation attribute is present
When it happens
Trigger: An implementation attribute set to a simple class name (or any string equal to several permitted subclasses' names/canonical names) on a sealed configuration type, e.g. implementation="Default" where two permitted classes in different packages are both named Default.
Common situations: Large APIs with several permitted implementations sharing simple names (Default, Impl, Simple); configuration snippets that rely on simple names across packages.
Related errors
- Cannot find permitted subclass '{}' for sealed type {}
- Cannot set default
- Cannot find '{}' in {}
- Cannot read metadata from '{}'
- Unable to lookup org.eclipse.aether.RepositorySystem
AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21).
Data as JSON: /api/errors/cc0d59e2daf0190d.
Report an issue: GitHub.