karatelabs/karate · error · RuntimeException

start() argument must be a string path or config map

Error message

start() argument must be a string path or config map

What it means

karate.start() starts an embedded MockServer from within a JS block. It accepts exactly two shapes of arguments: a string path to a feature file (karate.start('api.feature')) or a config map with a 'mock' key (karate.start({mock: 'api.feature', port: 8080})). Karate throws this error when the argument is neither a String nor a Map — the library cannot interpret any other type as a mock definition.

Solutions

  1. Pass a string path to the feature file: karate.start('api.feature')
  2. Pass a config map with a 'mock' key: karate.start({mock: 'api.feature', port: 8080})
  3. If passing a variable, confirm it holds a string path (print it before calling start())
  4. To start multiple mocks, call karate.start() once per feature path instead of passing an array

Example fix

// before
var port = 8080;
var server = karate.start(port); // fails: number is not a path or map

// after
var server = karate.start({ mock: 'api.feature', port: 8080 });
Defensive patterns

Strategy: validation

Validate before calling

// JS in scenario
var arg = /* value to pass */;
if (typeof arg !== 'string' && (typeof arg !== 'object' || arg === null || Array.isArray(arg))) {
  throw new Error('karate.start() needs a feature path string or a config map, got: ' + typeof arg);
}
var server = karate.start(arg);

Type guard

function isStartArg(v) {
  return typeof v === 'string' || (v !== null && !Array.isArray(v) && typeof v === 'object');
}

Try / catch

try {
  var server = karate.start(arg);
} catch (e) {
  if (('' + e).indexOf('must be a string path or config map') !== -1) {
    karate.log('bad start() argument, expected string path or {mock: ...} map');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling karate.start() with an argument that is not a string and not a Map — e.g. karate.start(8080), karate.start(['api.feature']), karate.start(someJavaObject), or a JS object that arrives as a non-Map bridged type.

Common situations: Developers assume start() takes a port number like MockServer.builder(); or they pass an array of feature paths expecting multiple mocks to start; or a variable holding the feature path was accidentally overwritten with a non-string value in the scenario.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

                    builder.port(((Number) config.get("port")).intValue());
                }
                if (config.containsKey("ssl")) {
                    builder.ssl(Boolean.TRUE.equals(config.get("ssl")));
                }
                if (config.containsKey("cert")) {
                    builder.certPath((String) config.get("cert"));
                }
                if (config.containsKey("key")) {
                    builder.keyPath((String) config.get("key"));
                }
                if (config.containsKey("arg")) {
                    builder.arg((Map<String, Object>) config.get("arg"));
                }
                if (config.containsKey("pathPrefix")) {
                    builder.pathPrefix((String) config.get("pathPrefix"));
                }
            } else {
                throw new RuntimeException("start() argument must be a string path or config map");
            }

            return builder.start();
        };
    }

    /**
     * karate.proceed() - Forward the current request to a target URL (proxy mode).
     * Can only be used within a mock scenario.
     * Usage:
     * <pre>
     * // Forward to specific target
     * var response = karate.proceed('http://backend:8080');
     *
     * // Forward using Host header from request
     * var response = karate.proceed();
     * </pre>
     */

View on GitHub (pinned to a22eb90246)