{"record":{"id":"43fe6e3e3aee904e","repo":"karatelabs/karate","slug":"error-waiting-for-process","errorCode":null,"errorMessage":"error waiting for process","messagePattern":"error waiting for process","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/process/ProcessHandle.java","lineNumber":331,"sourceCode":"                        future.complete(line);\n                    }\n                }\n            } catch (Exception e) {\n                logger.warn(\"waitForOutput predicate error: {}\", e.getMessage());\n            }\n        }\n    }\n\n    // ========== Public API ==========\n\n    public int waitSync() {\n        try {\n            int code = exitFuture.get();\n            // Wait for stream readers to complete so all output is captured\n            waitForStreamReaders();\n            return code;\n        } catch (Exception e) {\n            throw new RuntimeException(\"error waiting for process\", e);\n        }\n    }\n\n    public int waitSync(long timeoutMillis) {\n        try {\n            int code = exitFuture.get(timeoutMillis, TimeUnit.MILLISECONDS);\n            // Wait for stream readers to complete so all output is captured\n            waitForStreamReaders();\n            return code;\n        } catch (TimeoutException e) {\n            throw new RuntimeException(\"process timed out after \" + timeoutMillis + \"ms\");\n        } catch (Exception e) {\n            throw new RuntimeException(\"error waiting for process\", e);\n        }\n    }\n\n    /**\n     * Wait for all stream reader threads to complete.","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/process/ProcessHandle.java#L313-L349","documentation":"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.","triggerScenarios":"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().","commonSituations":"Interrupting test threads (test timeouts, ExecutorService.shutdownNow), the spawned process's watcher failing, or JVM shutdown hooks racing the wait.","solutions":["Inspect the wrapped cause; if it's InterruptedException, review who interrupts the waiting thread (test framework timeouts, executor shutdown)","Avoid interrupting threads that are blocked in waitSync; use the timed variant waitSync(timeoutMillis) with explicit timeout handling","Ensure the process and handle are used within one thread lifecycle and not orphaned across executor shutdowns"],"exampleFix":"// before\nint code = handle.waitSync(); // interrupted by executor shutdownNow\n// after\nboolean done = handle.waitForExit(30_000); // or waitSync(timeout) with explicit handling\nif (!done) { /* handle timeout rather than uncontrolled interruption */ }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    int code = handle.waitSync();\n} catch (RuntimeException e) {\n    if (e.getMessage().equals(\"error waiting for process\") && e.getCause() instanceof InterruptedException) {\n        Thread.currentThread().interrupt(); // restore interrupt status\n    } else {\n        throw e;\n    }\n}","preventionTips":["Prefer waitSync(timeoutMillis) over the unbounded variant","Don't interrupt threads blocked on process waits (avoid shutdownNow on their executor)","Keep process handling on a dedicated thread with a clear lifecycle"],"tags":["process","wait","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"}