karatelabs/karate · error · RuntimeException

CDP error

Error message

CDP error: {message}

What it means

CdpClient.send() rethrows non-timeout failures from the async send: if the cause is a RuntimeException it propagates directly; otherwise it is wrapped as 'CDP error: <cause message>'. This is the generic wrapper for any CDP command failure that is not a timeout or already a RuntimeException.

Solutions

  1. Inspect the chained cause (getCause()) for the root problem — socket closed, browser crashed, etc.
  2. Verify the browser is still running; relaunch the driver if the session died
  3. Check CI stability: resource limits (memory) that kill the browser mid-run
  4. Retry flaky steps; wrap driver interactions with retry for transient socket failures

Example fix

// before
CdpResponse resp = client.method("Page.navigate").param("url", url).send(); // browser died -> 'CDP error'
// after: guard with liveness check
if (karate.driver.isTerminated() == false) {
    CdpResponse resp = client.method("Page.navigate").param("url", url).send();
} else {
    karate.driver = karate.driverManager.restart();
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (driver.isTerminated()) { driver = restartDriver(); } // skip send on dead session

Type guard

null

Try / catch

try { CdpResponse r = client.method(m).send(); }
catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("CDP error:")) {
        logger.error("CDP root cause:", e.getCause());
        throw new DriverException("browser session unhealthy", e.getCause());
    }
    throw e;
}

Prevention

When it happens

Trigger: Underlying sendAsync fails with a checked/non-runtime cause (IO errors, closed websocket wrapped in CompletionException); any unexpected completion exception from the CDP future chain.

Common situations: Websocket closed mid-command (browser crashed or exited); IO errors on the DevTools socket in flaky CI environments; internal client failures surfacing through the CompletionException unwrap path.

Related errors


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

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/driver/cdp/CdpClient.java:275

    }

    // Send methods

    /**
     * Blocking send with response.
     */
    CdpResponse send(CdpMessage message) {
        try {
            return sendAsync(message).join();
        } catch (CompletionException e) {
            Throwable cause = e.getCause();
            if (cause instanceof TimeoutException) {
                throw new RuntimeException("CDP timeout for: " + message.getMethod());
            }
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            }
            throw new RuntimeException("CDP error: " + cause.getMessage(), cause);
        }
    }

    /**
     * Async send with response tracking.
     */
    CompletableFuture<CdpResponse> sendAsync(CdpMessage message) {
        // Fail fast if connection is closed
        if (!ws.isOpen()) {
            return CompletableFuture.failedFuture(
                    new WsException(WsException.Type.CONNECTION_CLOSED, "websocket not open"));
        }

        CompletableFuture<CdpResponse> future = new CompletableFuture<>();
        int messageId = message.getId();
        pending.put(messageId, new PendingRequest(future, message.getMethod()));

        String json = message.toJson();

View on GitHub (pinned to a22eb90246)