{"record":{"id":"3d47477592488075","repo":"karatelabs/karate","slug":"interrupted-while-waiting-for-driver","errorCode":null,"errorMessage":"Interrupted while waiting for driver","messagePattern":"Interrupted while waiting for driver","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"karate-core/src/main/java/io/karatelabs/driver/PooledDriverProvider.java","lineNumber":223,"sourceCode":"            // handed out to the next scenario.\n            if (driver.isTerminated()) {\n                createdCount.decrementAndGet();\n                driver = createDriver(config);\n                createdCount.incrementAndGet();\n                logger.info(\"Replaced terminated driver for scenario: {}\", scenarioName);\n            } else if (!resetDriver(driver)) {\n                closeDriverQuietly(driver);\n                createdCount.decrementAndGet();\n                driver = createDriver(config);\n                createdCount.incrementAndGet();\n                logger.info(\"Replaced unhealthy driver for scenario: {}\", scenarioName);\n            } else {\n                logger.info(\"Acquired pooled driver after wait for scenario: {}\", scenarioName);\n            }\n            return driver;\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            throw new RuntimeException(\"Interrupted while waiting for driver\", e);\n        }\n    }\n\n    @Override\n    public void release(ScenarioRuntime runtime, Driver driver) {\n        assignedDrivers.remove(runtime);\n\n        if (shutdown) {\n            // During shutdown, just close the driver\n            closeDriverQuietly(driver);\n            return;\n        }\n\n        if (driver.isTerminated()) {\n            logger.debug(\"Not returning terminated driver to pool\");\n            createdCount.decrementAndGet();\n            return;\n        }","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-core/src/main/java/io/karatelabs/driver/PooledDriverProvider.java#L205-L241","documentation":"The thread waiting in waitForDriver on availableDrivers.poll(30, TimeUnit.SECONDS) was interrupted. The code restores the interrupt flag and rethrows as a RuntimeException. This is almost never a browser/driver problem — something interrupted the test thread while it waited for a pooled driver.","triggerScenarios":"Executor/executor-service shutdown during a running suite; JUnit/TestNG or Surefire cancelling the run (timeout, Ctrl-C, fail-fast); another component calling Thread.interrupt() on the Karate thread while it blocks in acquire().","commonSituations":"Build tool timeout killing the forked JVM mid-run; a plugin shutting down its thread pool while scenarios are queued; mis-behaving parallel test frameworks interrupting worker threads at teardown; graceful-shutdown paths racing with in-flight acquire().","solutions":["Find what interrupts the thread (executor shutdown, framework timeout) and delay that until all scenarios finish","Ensure shutdown/teardown hooks run only after all acquire() calls complete","Increase the build/framework timeout so the run isn't cancelled mid-wait","Check for competing shutdown code in your own test harness that calls executorService.shutdownNow() prematurely"],"exampleFix":"// before: shutdownNow while scenarios still queued\nexecutor.submit(() -> runner.run());\nexecutor.shutdownNow(); // interrupts waiting acquire()\n// after: wait for completion first\nexecutor.submit(() -> runner.run());\nexecutor.shutdown();\nexecutor.awaitTermination(10, TimeUnit.MINUTES); // no interrupt while waiting","handlingStrategy":"try-catch","validationCode":"// avoid interrupting worker threads: check executor state before submission\nif (executor.isShutdown()) { throw new IllegalStateException(\"executor already shut down\"); }","typeGuard":"null","tryCatchPattern":"try { Driver d = provider.acquire(runtime, config); }\ncatch (RuntimeException e) {\n    if (e.getCause() instanceof InterruptedException) {\n        Thread.currentThread().interrupt(); // preserve flag, abort gracefully\n        return;\n    }\n    throw e;\n}","preventionTips":["Never call shutdownNow() while scenarios may still be acquiring drivers","Use awaitTermination after shutdown instead of forced interrupts","Configure build timeouts longer than the worst-case suite duration","Keep teardown hooks out of the acquire path"],"tags":["threading","interruption","driver-pool"],"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"}