{"record":{"id":"2093c0ce30b38ff9","repo":"apache/dubbo","slug":"extension-type-null-2093c0","errorCode":null,"errorMessage":"Extension type == null","messagePattern":"Extension type == null","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java","lineNumber":947,"sourceCode":"\n    /**\n     * return true if and only if:\n     * <p>\n     * 1, public\n     * <p>\n     * 2, name starts with \"set\"\n     * <p>\n     * 3, only has one parameter\n     */\n    private boolean isSetter(Method method) {\n        return method.getName().startsWith(\"set\")\n                && method.getParameterTypes().length == 1\n                && Modifier.isPublic(method.getModifiers());\n    }\n\n    private Class<?> getExtensionClass(String name) {\n        if (type == null) {\n            throw new IllegalArgumentException(\"Extension type == null\");\n        }\n        if (name == null) {\n            throw new IllegalArgumentException(\"Extension name == null\");\n        }\n        return getExtensionClasses().get(name);\n    }\n\n    private Map<String, Class<?>> getExtensionClasses() {\n        Map<String, Class<?>> classes = cachedClasses.get();\n        if (classes == null) {\n            loadExtensionClassesLock.lock();\n            try {\n                classes = cachedClasses.get();\n                if (classes == null) {\n                    try {\n                        classes = loadExtensionClasses();\n                    } catch (InterruptedException e) {\n                        logger.error(","sourceCodeStart":929,"sourceCodeEnd":965,"githubUrl":"https://github.com/apache/dubbo/blob/3a3043227f5571d25eb2889de5bca22f2914843b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java#L929-L965","documentation":"Thrown by getExtensionClass(String name) when the ExtensionLoader's internal 'type' field (the SPI interface) is null. The type field is set in the ExtensionLoader constructor from the interface passed to ExtensionLoader.getExtensionLoader(Class). This error indicates the loader was created or corrupted in a way that left the SPI interface unset - an internal invariant violation rather than a user configuration problem.","triggerScenarios":"getExtensionClass(name) is called on an ExtensionLoader instance whose type field is null. This is only reachable if an ExtensionLoader was constructed with a null interface argument or if the type field was reflectively cleared - ExtensionLoader.getExtensionLoader(Class) itself validates non-null at entry, so normal API use should not reach this.","commonSituations":"Test code that constructs ExtensionLoader directly via reflection instead of through getExtensionLoader(); a framework bug or a custom fork that bypasses the factory method; corruption from a classloader-reloading scenario that nulls internal fields.","solutions":["Always obtain an ExtensionLoader via ExtensionLoader.getExtensionLoader(MySpiInterface.class) - never construct one directly.","If using the ExtensionDirector API, obtain loaders through extensionDirector.getExtensionLoader(Class) which manages type correctly.","In tests, ensure you pass a concrete interface Class object, not null."],"exampleFix":"// before\nExtensionLoader loader = someDirector.getExtensionLoader(null);\nloader.getExtension(\"foo\"); // throws [142]\n\n// after\nExtensionLoader<MySpi> loader = extensionDirector.getExtensionLoader(MySpi.class);\nloader.getExtension(\"foo\");","handlingStrategy":"validation","validationCode":"// Always obtain loaders through the factory, which validates non-null type\npublic static <T> ExtensionLoader<T> safeLoader(ExtensionDirector d, Class<T> type) {\n    java.util.Objects.requireNonNull(type, \"SPI interface type must not be null\");\n    return d.getExtensionLoader(type);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never construct ExtensionLoader directly - always use ExtensionLoader.getExtensionLoader(Class) or ExtensionDirector.getExtensionLoader(Class).","Pass concrete interface Class objects, never null.","In tests, assert the loader is non-null and typed before use."],"tags":["dubbo-spi","precondition","internal-api","extension-loader"],"backgroundTag":null,"analyzedSha":"3a3043227f5571d25eb2889de5bca22f2914843b","analyzedAt":"2026-08-14T00:43:19.853Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}