karatelabs/karate · error · RuntimeException

error in waitForOutput

Error message

error in waitForOutput

What it means

ProcessHandle.waitForOutput() blocks waiting for process stdout to match a predicate; if the wait is interrupted or fails for any reason, the original exception is wrapped in a RuntimeException with this message. It differs from the timeout message ('waitForOutput timed out'), so hitting this means an unexpected interruption or error, not just a slow process.

Solutions

  1. Inspect the cause (e.getCause()) to find the real failure — usually InterruptedException or an exception thrown inside the predicate
  2. Make the predicate body defensive: wrap predicate logic in try-catch or avoid throwing on unexpected lines
  3. Avoid interrupting the thread that called waitForOutput while the process is still running
  4. Check that the process itself is alive and producing output; a dead process with a never-true predicate keeps the wait open until interrupted

Example fix

// before
karate.waitForOutput(line -> line.contains(parsedToken)) // predicate may throw on null/odd lines
// after
karate.waitForOutput(line -> {
    try { return line != null && line.contains(parsedToken); }
    catch (Exception e) { return false; }
});
Defensive patterns

Strategy: try-catch

Validate before calling

// before waiting, ensure the process is alive
if (!p.isAlive()) { throw new IllegalStateException('process exited before waitForOutput'); }

Try / catch

try {
  p.waitForOutput(line => line.includes('READY'), 5000);
} catch (e) {
  if (String(e.message).indexOf('timed out') >= 0) { /* handle timeout */ }
  else { karate.log('waitForOutput interrupted: ' + e.cause); throw e; }
}

Prevention

When it happens

Trigger: Calling waitForOutput(predicate, timeout) when the waiting thread is interrupted (InterruptedException) or the underlying wait mechanism throws any Exception other than the timeout condition.

Common situations: Test frameworks cancelling/interrupting scenario threads mid-wait; JVM shutdown while a process listener thread waits; a bug in a custom predicate that throws while being evaluated against output lines.

Related errors


AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/6e0eb0d082d790c9. Report an issue: GitHub.

Appendix: source

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

     */
    public String waitForOutput(Predicate<String> predicate, long timeoutMillis) {
        CompletableFuture<String> future = new CompletableFuture<>();
        waitPredicates.add(predicate);
        waitFutures.put(predicate, future);
        try {
            if (timeoutMillis > 0) {
                return future.get(timeoutMillis, TimeUnit.MILLISECONDS);
            } else {
                return future.get();
            }
        } catch (TimeoutException e) {
            waitPredicates.remove(predicate);
            waitFutures.remove(predicate);
            throw new RuntimeException("waitForOutput timed out after " + timeoutMillis + "ms");
        } catch (Exception e) {
            waitPredicates.remove(predicate);
            waitFutures.remove(predicate);
            throw new RuntimeException("error in waitForOutput", e);
        }
    }

    public String getStdOut() {
        synchronized (stdoutBuffer) {
            return stdoutBuffer.toString();
        }
    }

    public String getStdErr() {
        synchronized (stderrBuffer) {
            return stderrBuffer.toString();
        }
    }

    public int getExitCode() {
        return exitCode;
    }

View on GitHub (pinned to a22eb90246)