karatelabs/karate · error · RuntimeException

waitForOutput requires a function argument

Error message

waitForOutput requires a function argument

What it means

ProcessHandle.waitForOutput(predicate) blocks until a stdout line makes the JS predicate return true. The binding requires the first argument to be a function; missing or non-function arguments throw this RuntimeException. A numeric second argument is the optional timeout in millis.

Solutions

  1. Wrap the condition: p.waitForOutput(line => line.includes('READY'))
  2. Optionally pass a second numeric argument as timeout: waitForOutput(pred, 5000)
  3. If you just want to wait for exit, use wait() / waitSync() instead of waitForOutput

Example fix

// before
p.waitForOutput('READY');
// after
p.waitForOutput(line => line.includes('READY'), 10000);
Defensive patterns

Strategy: type-guard

Validate before calling

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

Type guard

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

Try / catch

try {
  p.waitForOutput(pred, 10000);
} catch (e) {
  karate.log('waitForOutput failed: ' + e.message);
}

Prevention

When it happens

Trigger: Calling process.waitForOutput() with no arguments (it is not a plain wait), or passing a string/regex/object instead of a function as the first argument.

Common situations: Migrating from a wait(timeout) call and assuming waitForOutput() takes a number; passing a regex literal directly hoping the library applies it; forgetting to wrap a condition in a function.

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

Appendix: source

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

                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) -> {
                if (args.length == 0 || !(args[0] instanceof JavaCallable)) {
                    throw new RuntimeException("waitForOutput requires a function argument");
                }
                JavaCallable predicate = (JavaCallable) args[0];
                long timeout = args.length > 1 && args[1] instanceof Number
                        ? ((Number) args[1]).longValue() : 0;
                return waitForOutput(line -> {
                    Object res = predicate.call(ctx, line);
                    return Boolean.TRUE.equals(res);
                }, timeout);
            };
            case "close" -> (JavaCallable) (ctx, args) -> {
                boolean force = args.length > 0 && Boolean.TRUE.equals(args[0]);
                close(force);
                return null;
            };
            case "signal" -> (JavaCallable) (ctx, args) -> {
                if (args.length > 0) {
                    signal(args[0]);
                }

View on GitHub (pinned to a22eb90246)