{"record":{"id":"6e0eb0d082d790c9","repo":"karatelabs/karate","slug":"error-in-waitforoutput","errorCode":null,"errorMessage":"error in waitForOutput","messagePattern":"error in waitForOutput","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/process/ProcessHandle.java","lineNumber":406,"sourceCode":"     */\n    public String waitForOutput(Predicate<String> predicate, long timeoutMillis) {\n        CompletableFuture<String> future = new CompletableFuture<>();\n        waitPredicates.add(predicate);\n        waitFutures.put(predicate, future);\n        try {\n            if (timeoutMillis > 0) {\n                return future.get(timeoutMillis, TimeUnit.MILLISECONDS);\n            } else {\n                return future.get();\n            }\n        } catch (TimeoutException e) {\n            waitPredicates.remove(predicate);\n            waitFutures.remove(predicate);\n            throw new RuntimeException(\"waitForOutput timed out after \" + timeoutMillis + \"ms\");\n        } catch (Exception e) {\n            waitPredicates.remove(predicate);\n            waitFutures.remove(predicate);\n            throw new RuntimeException(\"error in waitForOutput\", e);\n        }\n    }\n\n    public String getStdOut() {\n        synchronized (stdoutBuffer) {\n            return stdoutBuffer.toString();\n        }\n    }\n\n    public String getStdErr() {\n        synchronized (stderrBuffer) {\n            return stderrBuffer.toString();\n        }\n    }\n\n    public int getExitCode() {\n        return exitCode;\n    }","sourceCodeStart":388,"sourceCodeEnd":424,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/process/ProcessHandle.java#L388-L424","documentation":"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.","triggerScenarios":"Calling waitForOutput(predicate, timeout) when the waiting thread is interrupted (InterruptedException) or the underlying wait mechanism throws any Exception other than the timeout condition.","commonSituations":"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.","solutions":["Inspect the cause (e.getCause()) to find the real failure — usually InterruptedException or an exception thrown inside the predicate","Make the predicate body defensive: wrap predicate logic in try-catch or avoid throwing on unexpected lines","Avoid interrupting the thread that called waitForOutput while the process is still running","Check that the process itself is alive and producing output; a dead process with a never-true predicate keeps the wait open until interrupted"],"exampleFix":"// before\nkarate.waitForOutput(line -> line.contains(parsedToken)) // predicate may throw on null/odd lines\n// after\nkarate.waitForOutput(line -> {\n    try { return line != null && line.contains(parsedToken); }\n    catch (Exception e) { return false; }\n});","handlingStrategy":"try-catch","validationCode":"// before waiting, ensure the process is alive\nif (!p.isAlive()) { throw new IllegalStateException('process exited before waitForOutput'); }","typeGuard":null,"tryCatchPattern":"try {\n  p.waitForOutput(line => line.includes('READY'), 5000);\n} catch (e) {\n  if (String(e.message).indexOf('timed out') >= 0) { /* handle timeout */ }\n  else { karate.log('waitForOutput interrupted: ' + e.cause); throw e; }\n}","preventionTips":["Always pass a finite timeout so waits terminate normally","Keep predicate logic simple and exception-free","Avoid interrupting the scenario thread while a wait is pending","Check process liveness before long waits"],"tags":["process","java","concurrency","interrupted"],"backgroundTag":"thread-interrupted","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}