karatelabs/karate · error · RuntimeException

exec() argument must be string, array, or object

Error message

exec() argument must be string, array, or object

What it means

Karate's JS `karate.exec()` accepts a command as a string (shell command line), a List/array of args, or a Map (process config). The library throws this RuntimeException when the first argument is none of those types, refusing to guess how to launch a process from an unrecognized value.

Solutions

  1. Pass the command as a string: karate.exec('echo hello')
  2. Pass an array of arguments: karate.exec(['ls', '-la'])
  3. Pass a config Map (as accepted by ProcessBuilder.fromMap): karate.exec({ args: ['git', 'status'] })
  4. Log/inspect the argument with karate.log(typeof value) before calling exec() to confirm it is string/array/object

Example fix

// before
karate.exec(8080) // number, unsupported
// after
karate.exec('kill -9 ' + pid) // string command
Defensive patterns

Strategy: type-guard

Validate before calling

// JS
function isExecArg(v) { return typeof v === 'string' || Array.isArray(v) || (v !== null && typeof v === 'object' && !Array.isArray(v)); }
if (!isExecArg(arg)) throw new Error('exec() needs string, array, or object, got: ' + typeof arg);

Type guard

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

Try / catch

try { karate.exec(arg); } catch (e) { if (('' + e).indexOf('exec() argument must be') !== -1) { karate.log('bad exec arg type: ' + typeof arg); } throw e; }

Prevention

When it happens

Trigger: Calling karate.exec() with a first argument that is not a String, List, or Map — e.g. a Number (karate.exec(123)), null, a JS object that failed to convert to a Map, or a Boolean.

Common situations: Passing a numeric exit code or variable that was expected to be a string; forgetting to stringify a template result; copy-pasting a JS object literal where the library expects an options Map but a primitive slipped through; typos that leave the variable undefined in some scopes (undefined may arrive as a non-matching type).

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/f98217fde1e93a41. Report an issue: GitHub.

Appendix: source

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

     * karate.exec(['ls', '-la'])
     * karate.exec({ line: 'ls -la', workingDir: '/tmp' })
     */
    @SuppressWarnings("unchecked")
    private JavaInvokable exec() {
        return args -> {
            if (args.length == 0) {
                throw new RuntimeException("exec() needs at least one argument");
            }
            ProcessBuilder builder = ProcessBuilder.create();
            Object arg = args[0];
            if (arg instanceof String) {
                builder.line((String) arg);
            } else if (arg instanceof List) {
                builder.args((List<String>) arg);
            } else if (arg instanceof Map) {
                builder = ProcessBuilder.fromMap((Map<String, Object>) arg);
            } else {
                throw new RuntimeException("exec() argument must be string, array, or object");
            }
            ProcessHandle handle = ProcessHandle.start(builder.build());
            handle.waitSync();
            return handle.getStdOut();
        };
    }

    /**
     * karate.fork() - Asynchronous process execution.
     * Returns ProcessHandle for async control.
     * Usage:
     * var proc = karate.fork('ping google.com')
     * var proc = karate.fork({ args: ['node', 'server.js'], listener: fn })
     * var proc = karate.fork({ args: [...], start: false })  // deferred start
     * proc.onStdOut(fn).start()
     * proc.waitSync()
     * proc.stdOut
     * proc.exitCode

View on GitHub (pinned to a22eb90246)