karatelabs/karate · error · RuntimeException

exec() needs at least one argument

Error message

exec() needs at least one argument

What it means

karate.exec() runs an OS process, accepting either a command-line string or an options object ({ line, workingDir, ... }). The library throws this error when it is called with no arguments, because there is no command to execute; the ProcessBuilder would have nothing to run.

Solutions

  1. Pass a command string: karate.exec('ls -la').
  2. Or pass an options object with at least a line field: karate.exec({ line: 'ls -la', workingDir: '/tmp' }).
  3. Verify the command variable is defined and non-empty before the call, especially when sourced from config or env.
  4. Note karate.exec is for running processes; for shell steps inside scenarios use the exec/eval keywords in the feature file instead.

Example fix

// before
karate.exec()

// after
karate.exec({ line: 'mvn test', workingDir: '/tmp/project' })
Defensive patterns

Strategy: validation

Validate before calling

// JS, before calling
if (typeof cmd === 'string' && cmd.length > 0) {
  karate.exec(cmd);
} else if (cmd && typeof cmd === 'object' && typeof cmd.line === 'string') {
  karate.exec(cmd);
} else {
  throw new Error('exec() requires a command string or an object with a line field');
}

Type guard

function isExecArg(a) {
  return (typeof a === 'string' && a.length > 0) ||
         (a !== null && typeof a === 'object' && typeof a.line === 'string');
}

Try / catch

try {
  karate.exec(commandOrOptions);
} catch (e) {
  if (String(e.message).indexOf('exec() needs at least one argument') !== -1) {
    throw new Error('exec() called without a command — check config/env providing it');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling karate.exec() with zero arguments — typically when the command string or options object variable is undefined in the JS scope, or an empty options object was expected to carry defaults (it does not; at least one argument is required).

Common situations: Driving commands from environment-driven config where the command variable is unset; calling karate.exec() expecting it to inherit a previously configured command; refactors that moved the command into a variable that resolved to undefined.

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

Appendix: source

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

            return null;
        };
    }

    // ========== Process Execution ==========

    /**
     * karate.exec() - Synchronous process execution.
     * Returns stdout as string.
     * Usage:
     * karate.exec('ls -la')
     * 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();
        };
    }

View on GitHub (pinned to a22eb90246)