karatelabs/karate · error · RuntimeException

onStdOut requires a function argument

Error message

onStdOut requires a function argument

What it means

ProcessHandle.onStdOut() registers a JS callback invoked for each stdout line of the managed process. The library requires exactly that callback: calling onStdOut with no argument or with a non-function value is rejected at binding time with this RuntimeException.

Solutions

  1. Pass a JS function literal: karate.process(...).onStdOut(function(line){ ... })
  2. Verify the callback variable is defined and is a function, not a string naming it
  3. Register the listener before start() if you want to capture early output

Example fix

// before
var p = karate.start(...);
p.onStdOut('logLine');
// after
var p = karate.start(...);
p.onStdOut(line => karate.log('stdout: ' + line));
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof listener !== 'function') { throw new Error('listener must be a function'); }

Type guard

function isFn(x) { return typeof x === 'function'; }

Try / catch

try {
  p.onStdOut(listener);
} catch (e) {
  karate.log('onStdOut registration failed: ' + e.message);
}

Prevention

When it happens

Trigger: Calling process.onStdOut() with zero arguments, or passing a string/number/object instead of a JS function (e.g. onStdOut('handleLine') or onStdOut(someObject)).

Common situations: Typos where the intended callback variable is undefined or null; porting Java-style code that passes a method reference as a string; forgetting to define the listener before registering it.

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

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/process/ProcessHandle.java:498

    public Collection<String> jsKeys() {
        return KEYS;
    }

    @Override
    public Object jsGet(String key) {
        return switch (key) {
            case "stdOut" -> getStdOut();
            case "stdErr" -> getStdErr();
            case "exitCode" -> getExitCode();
            case "alive" -> isAlive();
            case "pid" -> getPid();
            case "start" -> (JavaCallable) (ctx, args) -> {
                start();
                return this;
            };
            case "onStdOut" -> (JavaCallable) (ctx, args) -> {
                if (args.length == 0 || !(args[0] instanceof JavaCallable)) {
                    throw new RuntimeException("onStdOut requires a function argument");
                }
                JavaCallable listener = (JavaCallable) args[0];
                onStdOut(line -> {
                    try {
                        listener.call(ctx, line);
                    } catch (Exception e) {
                        logger.warn("onStdOut listener error: {}", e.getMessage());
                    }
                });
                return this;
            };
            case "onStdErr" -> (JavaCallable) (ctx, args) -> {
                if (args.length == 0 || !(args[0] instanceof JavaCallable)) {
                    throw new RuntimeException("onStdErr requires a function argument");
                }
                JavaCallable listener = (JavaCallable) args[0];
                onStdErr(line -> {
                    try {

View on GitHub (pinned to a22eb90246)