karatelabs/karate · warning

pool size but webSocketUrl names a single page — all slots…

Error message

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: {}

What it means

When createDriver() is given a page-level webSocketUrl (does not contain /devtools/browser/) while poolSize > 1, every pooled driver connects to the SAME tab, so parallel scenarios will interfere. The provider logs this warning and falls back to CdpDriver.connect() on that single page instead of connectNewContext().

Solutions

  1. Use the browser-level webSocketUrl from http://host:port/json/version (contains /devtools/browser/) so each slot gets connectNewContext() and an isolated context
  2. Set poolSize to 1 if you intentionally share a single page
  3. Drop the explicit webSocketUrl and let Karate launch the browser itself for pooled runs

Example fix

// before
webSocketUrl: 'ws://localhost:9222/devtools/page/ABC123'
poolSize: 4
// after
webSocketUrl: 'ws://localhost:9222/devtools/browser/GUID-456'
poolSize: 4
Defensive patterns

Strategy: validation

Validate before calling

String ws = options.getWebSocketUrl();
if (ws != null && poolSize > 1 && !ws.contains("/devtools/browser/")) {
    throw new IllegalArgumentException(
        "webSocketUrl must be a browser-level endpoint (/devtools/browser/) when poolSize > 1: " + ws);
}

Type guard

boolean isBrowserLevel = ws -> ws != null && ws.contains("/devtools/browser/");

Prevention

When it happens

Trigger: Configuring karate with webSocketUrl pointing at a page target from /json/list or /json (contains /devtools/page/) instead of the browser endpoint from /json/version, with poolSize > 1.

Common situations: Copy-pasting a debug ws URL from a single Chrome session; using connectToChrome style config for pooled runs; mixing CDP connect examples with the pool feature.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

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

     * tab — that is inherent to the request, not something this method can fix.
     * </p>
     */
    protected Driver createDriver(Map<String, Object> config) {
        String type = (String) config.getOrDefault("type", "chrome");
        if (W3cBrowserType.isW3cType(type)) {
            return W3cDriver.start(config);
        }
        // CDP (default)
        CdpDriverOptions options = CdpDriverOptions.fromMap(config);
        String wsUrl = options.getWebSocketUrl();
        if (wsUrl == null || wsUrl.isEmpty()) {
            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).
     */

View on GitHub (pinned to a22eb90246)