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

  1. Pass a string: karate.fork('mvn spring-boot:run')
  2. Pass an array: karate.fork(['java', '-jar', 'app.jar'])
  3. Pass an options Map containing args: karate.fork({ args: ['java', '-jar', 'app.jar'], start: true })
  4. 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

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


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)