karatelabs/karate · error · RuntimeException
fork() argument must be string, array, or object
Error message
fork() argument must be string, array, or object
What it means
`karate.fork()` accepts a string command, an array of args, or a config Map (with options like `args`, `start`, listeners). After parsing optional Map options, the library throws this when the first argument was none of the supported types — meaning it reached the else branch of the type dispatch.
Solutions
- Pass a string: karate.fork('mvn spring-boot:run')
- Pass an array: karate.fork(['java', '-jar', 'app.jar'])
- Pass an options Map containing args: karate.fork({ args: ['java', '-jar', 'app.jar'], start: true })
- Stringify or restructure the argument before the call; verify its type with karate.type(value)
Example fix
// before
karate.fork(8080) // unsupported type
// after
karate.fork({ args: ['serve', '-p', '8080'] }) Defensive patterns
Strategy: type-guard
Validate before calling
// JS
function isForkArg(v) { return typeof v === 'string' || Array.isArray(v) || (v !== null && typeof v === 'object'); }
if (!isForkArg(arg)) throw new Error('fork arg must be string/array/object, got: ' + typeof arg); Type guard
function isForkArg(v) { return typeof v === 'string' || Array.isArray(v) || (v !== null && typeof v === 'object'); } Try / catch
try { karate.fork(arg); } catch (e) { if (('' + e).indexOf('fork() argument must be') !== -1) { karate.log('unsupported fork arg: ' + arg); } throw e; } Prevention
- Wrap commands in string, array, or { args: [...] } map
- Do not pass pids/ports/booleans to fork()
- Use karate.type(arg) to sanity-check before calling
When it happens
Trigger: karate.fork(<nonStringListMap>) — e.g. karate.fork(42), karate.fork(true), karate.fork(null), or a Map that was already consumed by the options branch pattern mismatch (a value typed as Number/Boolean instead of the expected types).
Common situations: Passing a port number instead of the command string; passing the result of an expression that returned a Boolean/Number; JSON parsed value that is a primitive rather than the expected array/object; migrating from another API where fork took a number (like a pid).
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
- exec() argument must be string, array, or object
- fork() needs at least one argument
- onStdOut requires a function argument
- onStdErr requires a function argument
- waitForOutput requires a function argument
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/3cabbe64835c1b97.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/core/KarateJs.java:901
// Extract errorListener function (receives line string directly)
Object errorListenerObj = options.get("errorListener");
if (errorListenerObj instanceof JavaCallable jsErrorListener) {
errorListener = line -> {
try {
jsErrorListener.call(null, line);
} catch (Exception e) {
logger.warn("process errorListener error: {}", e.getMessage());
}
};
}
// Check start option (default true)
Object startObj = options.get("start");
if (startObj instanceof Boolean) {
autoStart = (Boolean) startObj;
}
} else {
throw new RuntimeException("fork() argument must be string, array, or object");
}
if (listener != null) {
builder.listener(listener);
}
if (errorListener != null) {
builder.errorListener(errorListener);
}
ProcessHandle handle = ProcessHandle.create(builder.build());
// Wire signal consumer for listen/listenResult integration
ScenarioRuntime rt = getRuntime();
if (rt != null) {
handle.setSignalConsumer(rt::setListenResult);
}
if (autoStart) {View on GitHub (pinned to a22eb90246)