karatelabs/karate · error · RuntimeException

onStdErr requires a function argument

Error message

onStdErr requires a function argument

What it means

ProcessHandle.onStdErr() registers a JS callback invoked for each stderr line of the managed process. The binding validates that the first argument is a function; a missing or non-function argument throws this RuntimeException.

Solutions

  1. Pass an actual function: p.onStdErr(function(line){ ... })
  2. Guard optional listeners: only call onStdErr when (typeof listener === 'function')
  3. Remember the callback receives the raw line string

Example fix

// before
p.onStdErr(logger.error); // logger.error may be unbound / not a function in JS scope
// after
p.onStdErr(function(line){ karate.log('stderr: ' + line); });
Defensive patterns

Strategy: type-guard

Validate before calling

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

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: Calling process.onStdErr() with no arguments, or passing any non-callable value (string, number, plain object) as the first argument.

Common situations: Copy-paste from onStdOut where the callback was not defined; passing an object with a method instead of the function itself; accidentally passing null when the listener is optional.

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

Appendix: source

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

                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 {
                        listener.call(ctx, line);
                    } catch (Exception e) {
                        logger.warn("onStdErr listener error: {}", e.getMessage());
                    }
                });
                return this;
            };
            case "waitSync" -> (JavaCallable) (ctx, args) -> {
                if (args.length > 0 && args[0] instanceof Number) {
                    return waitSync(((Number) args[0]).longValue());
                }
                return waitSync();
            };
            case "waitForOutput" -> (JavaCallable) (ctx, args) -> {

View on GitHub (pinned to a22eb90246)