karatelabs/karate · warning

Error resetting driver state, will discard

Error message

Error resetting driver state, will discard: {}

What it means

resetDriver() prepares a pooled driver for the next scenario (navigating to about:blank, waitUntilReady, etc.). If any of those reset steps throw, the driver's channel is already sick, so the pool logs this and returns false meaning 'discard this driver'. This prevents recycling a driver whose websocket died or timed out.

Solutions

  1. No caller action needed — pool discards and creates a fresh driver; verify createdCount grows to poolSize
  2. If it happens every cycle, fix the underlying browser instability (memory, zombie chrome processes)
  3. Ensure waitUntilReady-compatible backends; update to a driver build with bounded readiness checks
Defensive patterns

Strategy: retry

Validate before calling

// pre-borrow sanity check
if (driver.isTerminated() || !driver.isResponsive()) { /* force discard + reborrow */ }

Try / catch

boolean ok = pool.resetDriver(driver, runtime);
if (!ok) { driver = pool.acquire(options, runtime); } // pool discards internally

Prevention

When it happens

Trigger: setUrl timeout, closed websocket, or any exception thrown during driver.reset() / waitUntilReady() when re-borrowing a pooled driver via takeHealthyFromPool() or waitForDriver().

Common situations: Browser tab crashed between scenarios; Chrome DevTools channel dropped after idle; network-stack wedge making even about:blank navigation hang then timeout.

Related errors


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

Appendix: source

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

            if (dialog != null) {
                logger.debug("Dismissing stale dialog before reset");
                try {
                    dialog.dismiss();
                } catch (Exception e) {
                    logger.debug("Dialog dismiss during reset (may already be handled): {}", e.getMessage());
                }
            }
            driver.setUrl("about:blank");
            driver.clearCookies();
            // Barrier on readiness before reuse: setUrl("about:blank") returns early
            // (about: URLs skip waitForPageLoad), so the fresh execution context may
            // still be settling. waitUntilReady() blocks until it is live so the next
            // scenario's first call never races a not-yet-ready context. No-op on
            // backends that establish readiness synchronously.
            driver.waitUntilReady();
        } catch (Exception e) {
            // Reset itself failed — channel is already sick (setUrl timeout, websocket closed, etc.)
            logger.warn("Error resetting driver state, will discard: {}", e.getMessage());
            return false;
        }
        // Post-reset liveness probe. setUrl("about:blank") can succeed on a driver that
        // will still hang on the next http:// navigation (seen after tab-switch.feature —
        // about:blank is local so Chrome handles it even when network-facing navigation
        // is stuck). A bounded Runtime.evaluate catches the degraded state before we
        // return the driver to the pool.
        if (!driver.isResponsive()) {
            logger.warn("Driver failed post-reset liveness probe, will discard");
            return false;
        }
        return true;
    }

    /**
     * Create a new driver from config.
     * Subclasses should override for custom driver creation (e.g., Testcontainers).
     * <p>

View on GitHub (pinned to a22eb90246)