karatelabs/karate · error · RuntimeException
CDP timeout for
Error message
CDP timeout for: {method} What it means
CdpClient.send() waits synchronously for a CDP response via CompletableFuture.join(). If the future completes with a TimeoutException, this RuntimeException is thrown naming the CDP method that timed out. The browser never replied to the command within the client's timeout window.
Solutions
- Retry the operation or the scenario — transient hangs often clear
- Check the browser process is alive and not frozen/paused (remove debugger pauses, attach no paused debugger)
- Increase the CDP timeout configuration if legitimate operations are slow
- Investigate page health: heavy scripts, endless navigation, or blocked renderer causing missed responses
- Reconnect/relaunch the driver if the websocket is dead
Example fix
// before: dialog blocks CDP processing, causing timeouts
Driver driver = karate.driver;
driver.dialog(); // auto-dismiss misconfigured -> page paused
// after: handle dialogs so CDP commands flow
karate.configure("driver", { type: 'chrome', addOptions: ['--headless=new'] });
// and use Dialog API to accept dialogs promptly Defensive patterns
Strategy: retry
Validate before calling
// ensure the browser session is alive before sending CDP commands
if (driver.isTerminated()) { driver = restartDriver(); } Type guard
null
Try / catch
try { CdpResponse r = client.method("Page.navigate").param("url", u).send(); }
catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("CDP timeout for:")) {
retryOnce(this::send); // or increase timeout
} else throw e;
} Prevention
- Avoid debugger pauses that block CDP processing
- Increase CDP timeout on slow pages/CI machines
- Handle dialogs promptly so commands are not queued indefinitely
- Monitor browser process health (OOM kills)
When it happens
Trigger: Sending a CDP command to a hung or closed browser; a command whose response is delayed beyond the CDP timeout (slow page, blocked renderer); websocket silently dropped so the response never arrives; commands sent while the target is paused in the debugger.
Common situations: Page stuck on a long navigation/script while Karate sends CDP commands; browser process frozen or OOM-killed; debugger breakpoint (paused) blocking command processing; slow CI machines exceeding the timeout; network.throttle or heavy resources delaying responses.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- CDP connection failed readiness check
- CDP error
- browser did not return a browserContextId
- page load timeout after
- Page.navigate timed out, retrying
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/95e5820e78660d56.
Report an issue: GitHub.
Appendix: source
Thrown at karate-core/src/main/java/io/karatelabs/driver/cdp/CdpClient.java:270
* Set the session ID for subsequent requests.
* Used when switching between page targets.
*/
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
// 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"));
}
View on GitHub (pinned to a22eb90246)