karatelabs/karate · error · RuntimeException

error waiting for process

Error message

error waiting for process

What it means

waitSync() (no-timeout variant) blocks on the process exit future and then on the stream readers; if waiting is interrupted or the exit future fails, it throws 'error waiting for process' wrapping the exception. It signals that the handle could not observe the process exit cleanly, not that the process exited non-zero.

Solutions

  1. Inspect the wrapped cause; if it's InterruptedException, review who interrupts the waiting thread (test framework timeouts, executor shutdown)
  2. Avoid interrupting threads that are blocked in waitSync; use the timed variant waitSync(timeoutMillis) with explicit timeout handling
  3. Ensure the process and handle are used within one thread lifecycle and not orphaned across executor shutdowns

Example fix

// before
int code = handle.waitSync(); // interrupted by executor shutdownNow
// after
boolean done = handle.waitForExit(30_000); // or waitSync(timeout) with explicit handling
if (!done) { /* handle timeout rather than uncontrolled interruption */ }
Defensive patterns

Strategy: try-catch

Try / catch

try {
    int code = handle.waitSync();
} catch (RuntimeException e) {
    if (e.getMessage().equals("error waiting for process") && e.getCause() instanceof InterruptedException) {
        Thread.currentThread().interrupt(); // restore interrupt status
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling waitSync()/exitCode()/exec() when the exitFuture completes exceptionally (I/O error in the exit-watcher), or the waiting thread is interrupted while blocked on exitFuture.get().

Common situations: Interrupting test threads (test timeouts, ExecutorService.shutdownNow), the spawned process's watcher failing, or JVM shutdown hooks racing the wait.

Related errors


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

Appendix: source

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

                        future.complete(line);
                    }
                }
            } catch (Exception e) {
                logger.warn("waitForOutput predicate error: {}", e.getMessage());
            }
        }
    }

    // ========== Public API ==========

    public int waitSync() {
        try {
            int code = exitFuture.get();
            // Wait for stream readers to complete so all output is captured
            waitForStreamReaders();
            return code;
        } catch (Exception e) {
            throw new RuntimeException("error waiting for process", e);
        }
    }

    public int waitSync(long timeoutMillis) {
        try {
            int code = exitFuture.get(timeoutMillis, TimeUnit.MILLISECONDS);
            // Wait for stream readers to complete so all output is captured
            waitForStreamReaders();
            return code;
        } catch (TimeoutException e) {
            throw new RuntimeException("process timed out after " + timeoutMillis + "ms");
        } catch (Exception e) {
            throw new RuntimeException("error waiting for process", e);
        }
    }

    /**
     * Wait for all stream reader threads to complete.

View on GitHub (pinned to a22eb90246)