{"record":{"id":"024b0cf21c8791b5","repo":"apache/dubbo","slug":"input-type-clazz-doesn-t-implement-the-extensio","errorCode":null,"errorMessage":"Input type ${clazz} doesn't implement the Extension ${type}","messagePattern":"Input type (.+?) doesn't implement the Extension (.+?)","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java","lineNumber":654,"sourceCode":"     */\n    public String getDefaultExtensionName() {\n        getExtensionClasses();\n        return cachedDefaultName;\n    }\n\n    /**\n     * Register new extension via API\n     *\n     * @param name  extension name\n     * @param clazz extension class\n     * @throws IllegalStateException when extension with the same name has already been registered.\n     */\n    public void addExtension(String name, Class<?> clazz) {\n        checkDestroyed();\n        getExtensionClasses(); // load classes\n\n        if (!type.isAssignableFrom(clazz)) {\n            throw new IllegalStateException(\"Input type \" + clazz + \" doesn't implement the Extension \" + type);\n        }\n        if (clazz.isInterface()) {\n            throw new IllegalStateException(\"Input type \" + clazz + \" can't be interface!\");\n        }\n\n        if (!clazz.isAnnotationPresent(Adaptive.class)) {\n            if (StringUtils.isBlank(name)) {\n                throw new IllegalStateException(\"Extension name is blank (Extension \" + type + \")!\");\n            }\n            if (cachedClasses.get().containsKey(name)) {\n                throw new IllegalStateException(\"Extension name \" + name + \" already exists (Extension \" + type + \")!\");\n            }\n\n            cachedNames.put(clazz, name);\n            cachedClasses.get().put(name, clazz);\n        } else {\n            if (cachedAdaptiveClass != null) {\n                throw new IllegalStateException(\"Adaptive Extension already exists (Extension \" + type + \")!\");","sourceCodeStart":636,"sourceCodeEnd":672,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java#L636-L672","documentation":"Thrown by ExtensionLoader.addExtension(String name, Class<?> clazz) when the provided class does not implement or extend the SPI interface type (type) that this ExtensionLoader manages. Dubbo requires that programmatically registered extensions are assignable to the extension point interface. The check uses type.isAssignableFrom(clazz).","triggerScenarios":"Calling addExtension with a class that implements a different interface or none at all. For example, registering MySerializer.class on an ExtensionLoader<Protocol> by mistake, or registering a class that was refactored to no longer implement the SPI interface.","commonSituations":"Developer registers a test stub or mock that forgot to implement the SPI interface. A copy-paste error uses the wrong ExtensionLoader instance. After refactoring, the implementation class was changed to extend a different base class and no longer satisfies the interface.","solutions":["Verify that clazz implements the interface that the ExtensionLoader was created for (the type field).","Ensure you are calling addExtension on the correct ExtensionLoader (for the right SPI type).","Make the class implement the SPI interface if it was supposed to."],"exampleFix":"// before — class doesn't implement the SPI interface\nloader.addExtension(\"custom\", WrongClass.class);\n// WrongClass does not implement Protocol\n\n// after\nclass CustomProtocol implements Protocol { ... }\nloader.addExtension(\"custom\", CustomProtocol.class);","handlingStrategy":"type-guard","validationCode":"if (!type.isAssignableFrom(clazz)) {\n    throw new IllegalStateException(\n        clazz + \" must implement \" + type.getName() + \" to be registered as an extension\");\n}\nloader.addExtension(name, clazz);","typeGuard":"static boolean implementsSpi(Class<?> implClass, Class<?> spiType) {\n    return implClass != null && spiType != null && spiType.isAssignableFrom(implClass);\n}","tryCatchPattern":null,"preventionTips":["Verify assignability with type.isAssignableFrom(clazz) before calling addExtension.","Ensure the implementation class genuinely implements the SPI interface (compile-time, not just runtime).","Write a unit test that validates all programmatically registered extensions satisfy the interface."],"tags":["dubbo-spi","type-validation","registration","extension-system"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}