{"record":{"id":"1b83757c9c301c7c","repo":"karatelabs/karate","slug":"boot-ext-name-classname-does-not-implement-io-karatelabs","errorCode":null,"errorMessage":"boot.ext('${name}'): ${className} does not implement io.karatelabs.core.Ext","messagePattern":"boot\\.ext\\('(.+?)'\\): (.+?) does not implement io\\.karatelabs\\.core\\.Ext","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/core/BootBinding.java","lineNumber":227,"sourceCode":"     * <p>Same name twice returns the same singleton instance.</p>\n     */\n    public Ext ext(String name) {\n        if (name == null || name.isBlank()) {\n            throw new IllegalArgumentException(\"boot.ext: name is null or empty\");\n        }\n        // Singleton-per-name within this BootBinding (which is itself per-Suite).\n        for (Ext existing : exts) {\n            if (name.equals(extShortName(existing))) {\n                return existing;\n            }\n        }\n        String className = extClassName(name);\n        Ext ext;\n        try {\n            Class<?> cls = Class.forName(className);\n            Object instance = cls.getDeclaredConstructor().newInstance();\n            if (!(instance instanceof Ext)) {\n                throw new RuntimeException(\n                        \"boot.ext('\" + name + \"'): \" + className\n                                + \" does not implement io.karatelabs.core.Ext\");\n            }\n            ext = (Ext) instance;\n        } catch (ClassNotFoundException e) {\n            throw new RuntimeException(\n                    \"boot.ext('\" + name + \"'): not on classpath. Expected \"\n                            + className + \" (name-convention resolution).\", e);\n        } catch (Exception e) {\n            throw new RuntimeException(\n                    \"boot.ext('\" + name + \"'): failed to construct \" + className\n                            + \" — \" + e.getMessage(), e);\n        }\n        // Fire onBoot eagerly per K43. Throws here fail the Suite.\n        ext.onBoot(suite);\n        exts.add(ext);\n        registrar.accept(ext);\n        logger.info(\"ext booted: {} ({})\", name, ext.getClass().getName());","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/core/BootBinding.java#L209-L245","documentation":"boot.ext(name) resolves the name to a class via the naming convention, instantiates it, and verifies the instance implements io.karatelabs.core.Ext. If the class loads but does not implement Ext, a RuntimeException is thrown naming both the requested extension and the offending class.","triggerScenarios":"A class exists at the name-convention location (so ClassNotFoundException does not fire) but it does not implement io.karatelabs.core.Ext — e.g. an unrelated class occupying the expected FQCN, or an Ext implementation compiled against a different package/version of the interface.","commonSituations":"Upgrading karate where the Ext interface package changed (e.g. io.karatelabs vs older package) leaving an old implementation in place; accidentally placing a helper class at the conventional extension FQCN; two extensions colliding on the same class name.","solutions":["Make the resolved class implement io.karatelabs.core.Ext (implement its methods).","Rebuild the extension against the karate version in use so it implements the current Ext interface/package.","Remove or rename the unrelated class occupying the name-convention FQCN.","Use a different extension name whose conventional class is free."],"exampleFix":"// before\npublic class MyExt { } // wrong package, no Ext interface\n// after\nimport io.karatelabs.core.Ext;\npublic class MyExt implements Ext {\n    public void onBoot(Suite suite) { }\n}","handlingStrategy":"validation","validationCode":"// before boot.ext(name), verify the class implements Ext\nClass<?> c = Class.forName(resolvedFqcn);\nif (!io.karatelabs.core.Ext.class.isAssignableFrom(c)) {\n    throw new IllegalStateException(resolvedFqcn + \" must implement io.karatelabs.core.Ext\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    boot.ext(name);\n} catch (RuntimeException e) {\n    // message names the offending class — fix its implements clause or rebuild against current karate\n}","preventionTips":["Always implement io.karatelabs.core.Ext from the same karate version you run against.","Rebuild extensions when upgrading karate.","Don't place unrelated classes at the extension naming-convention FQCN."],"tags":["boot","extension","classpath","type-mismatch"],"backgroundTag":"class-not-found","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}