karatelabs/karate · error · RuntimeException

channel() needs a type argument, e.g…

Error message

channel() needs a type argument, e.g. karate.channel('kafka')

What it means

Argument guard in the karate.channel() JS binding: the channel type (e.g. 'kafka') identifies which messaging/connector implementation to instantiate, and without it no channel can be created. Fires when karate.channel() is invoked with no arguments; pass a channel-type string.

Solutions

  1. Pass the channel type: karate.channel('kafka')
  2. Ensure the type variable is defined before the call
  3. Check available channel types (any registered factory, e.g. via a karate-<type> extension).

Example fix

// before
var ch = karate.channel();
// after
var ch = karate.channel('kafka');
Defensive patterns

Strategy: validation

Validate before calling

// JS
if (type == null) karate.fail('karate.channel requires a type');
var ch = karate.channel(type);

Type guard

function isChannelType(s) { return typeof s === 'string' && s.length > 0; }

Try / catch

try { var ch = karate.channel(type); } catch (e) { karate.warn('channel failed: ' + e); }

Prevention

When it happens

Trigger: `karate.channel()` with zero arguments; a dynamic type variable that is undefined causing an empty invocation.

Common situations: Configuring the channel type via a config value that was never set; writing generic helper JS that forgets the type parameter; typos dropped the argument during refactoring.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/core/KarateJs.java:1198

     * a JS function (e.g. iterating over a list of browser configs in a grid run),
     * where Gherkin steps aren't reachable per iteration. Returns the same instance
     * exposed via the {@code driver} root binding; after {@code driver.quit()} a
     * subsequent read re-inits cleanly via {@link ScenarioRuntime#getDriver()}.
     */
    private io.karatelabs.driver.Driver getDriverLazy() {
        ScenarioRuntime rt = getRuntime();
        if (rt == null) {
            throw new RuntimeException("karate.driver can only be read within a scenario");
        }
        return rt.getDriver();
    }

    // ========== Channel Support ==========

    private JavaInvokable channel() {
        return args -> {
            if (args.length == 0) {
                throw new RuntimeException("channel() needs a type argument, e.g. karate.channel('kafka')");
            }
            String type = args[0].toString();
            ScenarioRuntime rt = getRuntime();
            if (rt == null) {
                throw new RuntimeException("channel() can only be called within a scenario");
            }
            // An ext (e.g. boot.ext('grpc')) may have registered a factory on the Suite at boot;
            // it wins over the name-convention fallback. See Suite#registerChannelFactory.
            FeatureRuntime fr = rt.getFeatureRuntime();
            Suite suite = fr != null ? fr.getSuite() : null;
            ChannelFactory factory = suite != null ? suite.getChannelFactory(type) : null;
            try {
                if (factory == null) {
                    // No ext registered a factory for this type — resolve by name convention,
                    // mirroring boot.ext: channel('grpc') -> io.karatelabs.ext.grpc.GrpcChannelFactory.
                    String cap = Character.toUpperCase(type.charAt(0)) + type.substring(1);
                    String factoryClass = "io.karatelabs.ext." + type + "." + cap + "ChannelFactory";
                    Class<?> clazz = Class.forName(factoryClass);

View on GitHub (pinned to a22eb90246)