karatelabs/karate · warning

currentTargetId fallback to getPages()[0]

Error message

currentTargetId fallback to getPages()[0]: {} - parallel execution may be unreliable

What it means

During CdpDriver.initialize(), if no targetId could be derived from the connection URL, the driver falls back to getPages()[0] and warns that this is not safe for parallel execution — all fallback drivers would attach to the same first tab. It exists only for backwards compatibility with browser-level connections that expose no target id in the URL.

Solutions

  1. Connect with a URL that carries a target id, or use CdpDriver.connectNewContext() for browser-level endpoints so a fresh target is created
  2. Close extra tabs before connecting so getPages()[0] is the intended one
  3. Upgrade Chrome — newer builds provide per-target ws endpoints via /json/version
  4. For parallel runs, always ensure each driver gets its own target instead of relying on the fallback
Defensive patterns

Strategy: validation

Validate before calling

String ws = options.getWebSocketUrl();
if (ws != null && ws.contains("/devtools/browser/") && runningParallel) {
    // require connectNewContext path so each driver has its own targetId
}

Prevention

When it happens

Trigger: Connecting via CDP where the websocket URL does not embed a target id (older browser endpoint or custom proxy), so currentTargetId is null at initialize() time.

Common situations: Using a browser-level /devtools/browser/ URL with an older Chrome that does not auto-assign targets; custom DevTools proxies stripping target ids; connecting to an already-open Chrome with multiple tabs open.

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/d34f5c6e9e39cd17. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/driver/cdp/CdpDriver.java:617

        // CRITICAL: Get main frame ID FIRST - needed by event handlers
        // This works without Page.enable and ensures handlers can filter by frame
        CdpResponse frameResponse = cdp.method("Page.getFrameTree").send();
        mainFrameId = frameResponse.getResult("frameTree.frame.id");
        // Seed the committed-document tracker so the first setUrl's readyState
        // fallback can already tell the pre-existing document from the requested one.
        committedLoaderId = frameResponse.getResultAsString("frameTree.frame.loaderId");
        logger.debug("main frame ID: {}", mainFrameId);

        // Track current target for close() support
        // currentTargetId is set in constructor by extracting from WebSocket URL (preferred)
        // Fallback: if URL extraction failed (e.g., browser-level URL), use getPages()
        // Note: getPages() fallback is NOT safe for parallel execution - all drivers would
        // get the same targetId. This is only for backwards compatibility with browser-level connections.
        if (currentTargetId == null) {
            List<String> pages = getPages();
            if (!pages.isEmpty()) {
                currentTargetId = pages.get(0);
                logger.warn("currentTargetId fallback to getPages()[0]: {} - parallel execution may be unreliable", currentTargetId);
            }
        } else {
            logger.debug("current target ID (from URL): {}", currentTargetId);
        }

        // Resolve which browser context our tab lives in, so tab enumeration can be scoped
        // to it. Done by lookup rather than trusting ownedBrowserContextId: a driver that
        // merely connected to a page did not create that page's context but still must not
        // enumerate across into someone else's.
        browserContextId = lookupBrowserContextId(currentTargetId);
        logger.debug("browser context ID: {}", browserContextId == null ? "<default>" : browserContextId);

        // Setup event handlers BEFORE enabling domains
        // This prevents race conditions where events fire before handlers are registered
        setupEventHandlers();

        // Record the main page's session id BEFORE enabling domains so the Page.*
        // session filter has a reference value for the first wave of events.

View on GitHub (pinned to a22eb90246)