{"record":{"id":"dcc22814b46ff0f8","repo":"OpenAPITools/openapi-generator","slug":"can-t-instantiate-config-class-with-name-name","errorCode":null,"errorMessage":"Can't instantiate config class with name '{name}'. The class was found but could not be constructed; it must implement CodegenConfig, declare a public no-argument constructor, and that constructor must not throw.\nAvailable:\n{availableConfigs}","messagePattern":"Can't instantiate config class with name '(.+?)'\\. The class was found but could not be constructed; it must implement CodegenConfig, declare a public no-argument constructor, and that constructor must not throw\\.\nAvailable:\n(.+?)","errorType":"exception","errorClass":"GeneratorNotFoundException","httpStatus":null,"severity":"error","filePath":"modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConfigLoader.java","lineNumber":74,"sourceCode":"\n        // else try to load directly\n        try {\n            return loadConfigClass(name).asSubclass(CodegenConfig.class).getDeclaredConstructor().newInstance();\n        } catch (ClassNotFoundException e) {\n            throw generatorNotFoundException(name, availableConfigs, e);\n        } catch (NoClassDefFoundError e) {\n            if (e.getCause() instanceof ExceptionInInitializerError || hasInitializationFailed(name)) {\n                throw generatorInitializationException(name, availableConfigs, e);\n            }\n            throw generatorNotFoundException(name, availableConfigs, e);\n        } catch (UnsupportedClassVersionError e) {\n            throw generatorIncompatibleException(name, availableConfigs, e);\n        } catch (ExceptionInInitializerError e) {\n            throw generatorInitializationException(name, availableConfigs, e);\n        } catch (LinkageError e) {\n            throw generatorLinkageException(name, availableConfigs, e);\n        } catch (ReflectiveOperationException | ClassCastException e) {\n            throw new GeneratorNotFoundException(\n                    \"Can't instantiate config class with name '\" + name + \"'. The class was found but could not be \"\n                            + \"constructed; it must implement CodegenConfig, declare a public no-argument constructor, \"\n                            + \"and that constructor must not throw.\\nAvailable:\\n\" + availableConfigs, e);\n        } finally {\n            LOADING_CLASS_LOADER.remove();\n        }\n    }\n\n    public static List<CodegenConfig> getAll() {\n        List<CodegenConfig> output = new ArrayList<CodegenConfig>();\n        Set<String> configClasses = new HashSet<String>();\n        for (ClassLoader classLoader : getConfigClassLoaders()) {\n            ServiceLoader<CodegenConfig> loader = ServiceLoader.load(CodegenConfig.class, classLoader);\n            Iterator<ServiceLoader.Provider<CodegenConfig>> providers = loader.stream().iterator();\n            while (true) {\n                ServiceLoader.Provider<CodegenConfig> provider;\n                // Per-entry failures (missing/invalid provider class, LinkageError) happen after the\n                // cursor advances, so skip them and keep discovering. A resource-location failure","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/OpenAPITools/openapi-generator/blob/fcec517be3cf5b7964296bcba25fbc97541484e7/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConfigLoader.java#L56-L92","documentation":"Thrown by CodegenConfigLoader.forName(String) (called by CodegenConfigurator and the CLI's -g/--generator-name option) when the requested generator class WAS found on the classpath but could not be constructed. The exact branch is the catch of ReflectiveOperationException | ClassCastException around 'loadConfigClass(name).asSubclass(CodegenConfig.class).getDeclaredConstructor().newInstance()'. So either the class does not implement CodegenConfig (ClassCastException from asSubclass), has no public no-argument constructor (NoSuchMethodException), is not accessible (IllegalAccessException), or its constructor threw (InvocationTargetException). The message appends the list of available config names so you can pick a valid generator name.","triggerScenarios":"Passing -g <name> (or calling CodegenConfigLoader.forName(name)) where <name> resolves to a class that: (a) is not a CodegenConfig implementation (asSubclass throws ClassCastException), (b) only declares parameterized constructors so no public no-arg constructor exists, (c) is abstract or non-public, or (d) whose no-arg constructor throws (missing resource, NPE in field init). Note the sibling branches in the same try block produce DIFFERENT messages: ExceptionInInitializerError/NoClassDefFoundError-with-init-cause -> initialization error, UnsupportedClassVersionError -> incompatible, other LinkageError -> linkage, ClassNotFoundException -> GeneratorNotFound. This message appears only for reflective instantiation failure or wrong type.","commonSituations":"Writing a custom generator as a non-public or inner class; giving the custom generator only a constructor with arguments; a custom generator whose constructor reads a bundled resource or registers type mappings and throws when they are absent; compiling the generator against a different openapi-generator version than the one on the runtime classpath (changed supertypes -> ClassCastException); duplicate stale copies of the class in a shaded/uber jar; a typo'd generator name that accidentally matches another class on the classpath.","solutions":["Read the 'Available:' list in the message and use one of those exact generator names for -g; if the name you wanted is absent, your class is not on the classpath at all (different error branch).","If it is a custom generator: make the class public and top-level (or public static nested), implement CodegenConfig (normally by extending DefaultCodegen), and declare an explicit public no-argument constructor.","Inspect the chained cause in the stack trace: NoSuchMethodException => add a public no-arg constructor; IllegalAccessException => make the class/constructor public; InvocationTargetException => fix the exception the constructor itself threw (it is the innermost Caused by).","Rebuild and run the custom generator against the same openapi-generator version (mvn dependency the generator against the matching modules/openapi-generator artifact) to eliminate ClassCastException and AbstractMethodError from API drift.","If packaging a shaded jar, verify exactly one copy of the generator class and its dependencies exists (jar tf | grep <ClassName>) and remove stale duplicates."],"exampleFix":"// before\nclass MyJavaGenerator extends DefaultCodegen {\n    public MyJavaGenerator(String specVersion) { ... }\n}\n// after\npublic class MyJavaGenerator extends DefaultCodegen {\n    public MyJavaGenerator() { ... } // public, no-arg, must not throw\n}","handlingStrategy":"validation","validationCode":"// Pre-flight a generator name before CodegenConfigLoader.forName(name)\nClass<?> clazz;\ntry {\n    clazz = Class.forName(name, false, Thread.currentThread().getContextClassLoader());\n} catch (ClassNotFoundException e) {\n    throw new IllegalArgumentException(\"Generator class not on classpath: \" + name, e);\n}\nif (!org.openapitools.codegen.CodegenConfig.class.isAssignableFrom(clazz)) {\n    throw new IllegalArgumentException(name + \" does not implement CodegenConfig\");\n}\ntry {\n    java.lang.reflect.Constructor<?> ctor = clazz.getDeclaredConstructor();\n    if (!java.lang.reflect.Modifier.isPublic(clazz.getModifiers())\n            || !java.lang.reflect.Modifier.isPublic(ctor.getModifiers())) {\n        throw new IllegalArgumentException(name + \" and its no-arg constructor must be public\");\n    }\n} catch (NoSuchMethodException e) {\n    throw new IllegalArgumentException(name + \" lacks a public no-arg constructor\", e);\n}","typeGuard":"private static boolean isInstantiableGenerator(Class<?> c) {\n    return org.openapitools.codegen.CodegenConfig.class.isAssignableFrom(c)\n            && !Modifier.isAbstract(c.getModifiers())\n            && Modifier.isPublic(c.getModifiers());\n}","tryCatchPattern":"try {\n    CodegenConfig config = CodegenConfigLoader.forName(generatorName);\n} catch (RuntimeException e) {\n    // Distinguish wrapper vs cause: NoSuchMethodException => missing ctor,\n    // InvocationTargetException => ctor threw (unwrap getCause()).\n    Throwable root = Stream.iterate(e, Throwable::getCause)\n            .takeWhile(Objects::nonNull).reduce((a, b) -> b).orElse(e);\n    log.error(\"Generator '{}' failed to instantiate: {} - check Available list in message\",\n            generatorName, root);\n    throw e;\n}","preventionTips":["Smoke-test custom generators in CI: one test that calls CodegenConfigLoader.forName('yourGenerator') and asserts a non-null instance.","Pin the openapi-generator version used to compile and run custom generators to the same coordinate.","Run 'openapi-generator-cli list' after any dependency change to confirm custom generators are discoverable."],"tags":["java","openapi-generator","custom-generator","reflection","classpath","code-generator"],"backgroundTag":"reflection-class-instantiation-failure","analyzedSha":"fcec517be3cf5b7964296bcba25fbc97541484e7","analyzedAt":"2026-08-22T11:13:11.613Z","schemaVersion":2},"datasetVersion":"2026-08-22T14:17:55.899Z"}