{"record":{"id":"b9f5f0a2c0888569","repo":"apache/maven","slug":"cannot-find-permitted-subclass-for-sealed-typ","errorCode":null,"errorMessage":"Cannot find permitted subclass '{}' for sealed type {}","messagePattern":"Cannot find permitted subclass '(.+?)' for sealed type (.+?)","errorType":"exception","errorClass":"ComponentConfigurationException","httpStatus":null,"severity":"error","filePath":"impl/maven-core/src/main/java/org/apache/maven/configuration/internal/EnhancedConfigurationConverter.java","lineNumber":150,"sourceCode":"            final Class<?> type,\n            final String implementation,\n            final PlexusConfiguration configuration,\n            final ComponentConfigurationException cause)\n            throws ComponentConfigurationException {\n        final List<Class<?>> matches = new ArrayList<>();\n        for (Class<?> permittedSubclass : type.getPermittedSubclasses()) {\n            if (implementation.equals(permittedSubclass.getName())\n                    || implementation.equals(permittedSubclass.getCanonicalName())\n                    || implementation.equals(permittedSubclass.getSimpleName())) {\n                matches.add(permittedSubclass);\n            }\n        }\n\n        if (matches.size() == 1) {\n            return matches.get(0);\n        }\n        if (matches.isEmpty()) {\n            throw new ComponentConfigurationException(\n                    configuration,\n                    \"Cannot find permitted subclass '\" + implementation + \"' for sealed type \" + type.getName(),\n                    cause);\n        }\n        matches.sort(Comparator.comparing(Class::getName));\n\n        throw new ComponentConfigurationException(\n                configuration,\n                \"Implementation hint '\" + implementation + \"' is ambiguous for sealed type \" + type.getName() + \": \"\n                        + matches.stream().map(Class::getName).toList(),\n                cause);\n    }\n\n    public void processConfiguration(\n            final ConverterLookup lookup,\n            final Object bean,\n            final ClassLoader loader,\n            final PlexusConfiguration configuration,","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/apache/maven/blob/e4093d4e120eac99d6bdce5ba67cace2f3085c97/impl/maven-core/src/main/java/org/apache/maven/configuration/internal/EnhancedConfigurationConverter.java#L132-L168","documentation":"A plugin/component configuration uses an implementation='...' hint to choose an implementation of a sealed type, but the hint matches none of the sealed type's permitted subclasses. EnhancedConfigurationConverter.getPermittedSubclass() compares the hint against each permitted subclass's binary name, canonical name, and simple name; zero matches raise this error, chained onto the original lookup failure.","triggerScenarios":"Configuration like <param implementation=\"MyImpl\"> where the target type is a sealed interface and 'MyImpl' equals no Class in type.getPermittedSubclasses(): typo, wrong package, or a class that exists in the plugin realm but is not on the sealed type's permits list.","commonSituations":"Upgrading a library whose sealed interface replaced or removed a permitted subclass; configuration samples copied from a different library version; using a simple name when the intended class lives in another package.","solutions":["Use the fully qualified name of a class actually listed by the sealed type (check its javadoc or Class.getPermittedSubclasses())","Fix typos in the implementation attribute value","Omit the implementation attribute to let the converter use its default instantiation path","Align the plugin/library versions so the intended implementation is permitted by the sealed type"],"exampleFix":"<!-- before -->\n<param implementation=\"DefaultHandler\"/>\n\n<!-- after: fully qualified permitted subclass -->\n<param implementation=\"org.example.api.sealed.FileHandler\"/>","handlingStrategy":"validation","validationCode":"// Verify an implementation hint resolves before applying configuration\nClass<?> sealed = MySealedInterface.class;\nString hint = \"org.example.api.sealed.FileHandler\"; // from the configuration\nboolean permitted = Arrays.stream(sealed.getPermittedSubclasses())\n        .map(Class::getName)\n        .anyMatch(hint::equals);\nif (!permitted) {\n    throw new IllegalArgumentException(\"implementation '\" + hint + \"' is not permitted by \" + sealed.getName());\n}","typeGuard":"static Optional<Class<?>> resolvePermitted(Class<?> sealed, String hint) {\n    List<Class<?>> matches = Arrays.stream(sealed.getPermittedSubclasses())\n            .filter(c -> hint.equals(c.getName()) || hint.equals(c.getCanonicalName()) || hint.equals(c.getSimpleName()))\n            .toList();\n    return matches.size() == 1 ? Optional.of(matches.get(0)) : Optional.empty();\n}","tryCatchPattern":null,"preventionTips":["Always use fully qualified names in implementation attributes","After upgrading a library with sealed configuration types, re-check the permits list","Validate the hint against getPermittedSubclasses() in tests that assert configuration validity"],"tags":["maven","plexus","sealed-classes","plugin-configuration","java"],"backgroundTag":"invalid-implementation-class","analyzedSha":"e4093d4e120eac99d6bdce5ba67cace2f3085c97","analyzedAt":"2026-08-21T22:58:24.034Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}