karatelabs/karate · error · RuntimeException

boot.ext(' '): not on classpath. Expected (name-convention…

Error message

boot.ext('${name}'): not on classpath. Expected ${className} (name-convention resolution).

What it means

boot.ext(name) derives a fully-qualified class name from the given short name via naming convention and loads it with Class.forName. When the class is absent from the runtime classpath, a ClassNotFoundException is wrapped in a RuntimeException stating the expected class name so the developer knows exactly what to provide.

Solutions

  1. Add the extension's jar/dependency to the runtime classpath (Maven/Gradle dependency).
  2. Check the derived class name in the message and place your Ext implementation at exactly that fully-qualified name.
  3. Verify the extension module is compiled and included in the runtime source set/test classpath.
  4. Correct typos in the extension short name passed to boot.ext.

Example fix

// before
boot.ext('myext'); // class not on classpath
// after (pom.xml)
<dependency>
  <groupId>com.example</groupId>
  <artifactId>karate-ext-myext</artifactId>
  <version>1.0.0</version>
</dependency>
// then boot.ext('myext');
Defensive patterns

Strategy: validation

Validate before calling

// before boot.ext(name), check the convention-derived class is loadable
try {
    Class.forName("io.karatelabs.ext.MyExt"); // the FQCN the message reports
} catch (ClassNotFoundException e) {
    // dependency missing — add the extension artifact before booting
}

Try / catch

try {
    boot.ext(name);
} catch (RuntimeException e) {
    // read the expected class name from the message and add the missing dependency
}

Prevention

When it happens

Trigger: boot.ext('myext') where the convention-derived class (e.g. the Ext implementation for 'myext') is not on the test/runtime classpath — extension jar not declared as a dependency, wrong artifact, or class in a source set not compiled into the run.

Common situations: Forgot to add the extension Maven/Gradle dependency; extension implemented locally but under a package that doesn't match the name convention; running only the main source set while the ext lives in test sources; typo in the extension name.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/d4a1111a5a5fcfab. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/core/BootBinding.java:233

        // Singleton-per-name within this BootBinding (which is itself per-Suite).
        for (Ext existing : exts) {
            if (name.equals(extShortName(existing))) {
                return existing;
            }
        }
        String className = extClassName(name);
        Ext ext;
        try {
            Class<?> cls = Class.forName(className);
            Object instance = cls.getDeclaredConstructor().newInstance();
            if (!(instance instanceof Ext)) {
                throw new RuntimeException(
                        "boot.ext('" + name + "'): " + className
                                + " does not implement io.karatelabs.core.Ext");
            }
            ext = (Ext) instance;
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(
                    "boot.ext('" + name + "'): not on classpath. Expected "
                            + className + " (name-convention resolution).", e);
        } catch (Exception e) {
            throw new RuntimeException(
                    "boot.ext('" + name + "'): failed to construct " + className
                            + " — " + e.getMessage(), e);
        }
        // Fire onBoot eagerly per K43. Throws here fail the Suite.
        ext.onBoot(suite);
        exts.add(ext);
        registrar.accept(ext);
        logger.info("ext booted: {} ({})", name, ext.getClass().getName());
        return ext;
    }

    /**
     * {@code boot.has('name')} — is this ext available to boot? A pure classpath probe using the same
     * name convention as {@link #ext(String)}; constructs nothing and registers nothing.

View on GitHub (pinned to a22eb90246)