karatelabs/karate · warning

Error closing driver

Error message

Error closing driver: {}

What it means

closeDriverQuietly() attempts driver.quit() (only if not already terminated) and swallows any exception, logging this warning with e.getMessage(). It is a best-effort cleanup used when discarding dead or excess drivers, so the warning indicates quit failed but execution continues.

Solutions

  1. Check for leftover browser processes and clean them up (kill stale chrome between CI runs)
  2. Verify the browser/CDP versions match the driver expectations
  3. If the message is 'already closed' style, it is benign — filter or downgrade the log
  4. Ensure process killing (driver.process kill) works on the platform; some CI containers need extra privileges
Defensive patterns

Strategy: fallback

Validate before calling

if (!driver.isTerminated()) { /* safe to quit */ }

Type guard

boolean quittable = d -> d != null && !d.isTerminated();

Try / catch

try { if (!driver.isTerminated()) driver.quit(); } catch (Exception e) { /* already gone */ }

Prevention

When it happens

Trigger: driver.quit() throwing during pool discard — e.g. websocket already closed, CDP call timing out on a crashed browser, or the process already gone so the quit RPC fails.

Common situations: Browser killed externally (OOM, SIGKILL) while pooled; CDP channel broken mid-teardown; zombie chrome process lingering after a failed quit.

Related errors


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

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/driver/PooledDriverProvider.java:451

            return CdpDriver.start(options);
        }
        if (wsUrl.contains("/devtools/browser/")) {
            return CdpDriver.connectNewContext(wsUrl, options);
        }
        if (poolSize > 1) {
            logger.warn("pool size {} but webSocketUrl names a single page — all slots will drive the SAME tab."
                    + " Pass a browser-level endpoint (see /json/version) for isolated slots: {}", poolSize, wsUrl);
        }
        return CdpDriver.connect(wsUrl, options);
    }

    private void closeDriverQuietly(Driver driver) {
        try {
            if (!driver.isTerminated()) {
                driver.quit();
            }
        } catch (Exception e) {
            logger.warn("Error closing driver: {}", e.getMessage());
        }
    }

    /**
     * Get current pool size (may be -1 if not yet initialized).
     */
    public int getPoolSize() {
        return poolSize;
    }

    /**
     * Get current pool statistics for monitoring.
     */
    public String getStats() {
        return String.format("PooledDriverProvider[size=%d, created=%d, available=%d, assigned=%d]",
                poolSize, createdCount.get(),
                availableDrivers != null ? availableDrivers.size() : 0,
                assignedDrivers.size());

View on GitHub (pinned to a22eb90246)