karatelabs/karate · warning

retry started: (max attempts, ms interval)

Error message

retry started: {} (max {} attempts, {}ms interval)

What it means

This is a WARN log emitted by the CDP driver's centralized retry helper when it exhausts the first (non-retry) condition check and begins polling a condition. It indicates a condition passed to the retry mechanism (element wait, page readiness, etc.) did not hold on the first attempt, so Karate is entering a sleep-and-recheck loop up to maxAttempts with the given interval. It is diagnostic, not thrown: the condition may still succeed or fail later.

Solutions

  1. Treat as diagnostic; wait for the subsequent 'retry succeeded' or 'retry FAILED' log to know the outcome.
  2. If retries consistently trigger, increase waits/timeouts in the test or reduce page slowness rather than polling.
  3. If it never succeeds, inspect the condition's target (selector, URL, frame) — the retry loop is only masking a real failure.
  4. Check the thread is not being interrupted; interrupted threads abort retries early.
Defensive patterns

Strategy: retry

Prevention

When it happens

Trigger: Any call into CdpDriver's public retry path where the Supplier<Boolean> condition returns false or null on the very first evaluation — e.g. waiting for a DOM element, navigation state, or driver readiness that is not yet satisfied.

Common situations: Slow page loads or SPA hydration on first navigation; flaky CI environments where Chrome is slow to attach; waiting on async UI rendered after a click; an overly short initial condition check.

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.

Related errors


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

Appendix: source

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

    /**
     * Centralized retry mechanism with warning logging.
     * Use this for all retry operations to ensure consistent behavior and logging.
     *
     * @param description what we're waiting for (used in warning logs)
     * @param condition   returns true when the condition is met
     * @param maxAttempts maximum number of retry attempts (0 means try once)
     * @param interval    milliseconds between retries
     * @return true if condition was met, false if all retries exhausted
     */
    private boolean retry(String description, Supplier<Boolean> condition, int maxAttempts, int interval) {
        // First attempt (not a retry)
        if (Boolean.TRUE.equals(condition.get())) {
            return true;
        }

        // Log that we're starting retries (helps diagnose flaky tests)
        logger.warn("retry started: {} (max {} attempts, {}ms interval)", description, maxAttempts, interval);

        // Retry loop
        for (int attempt = 1; attempt <= maxAttempts; attempt++) {
            // Abort on interruption instead of degrading into a busy spin: sleep()
            // preserves the interrupt flag, so every later sleep would return
            // instantly and the remaining attempts would hammer CDP back-to-back.
            if (Thread.currentThread().isInterrupted()) {
                logger.warn("retry aborted (thread interrupted): {}", description);
                return false;
            }
            sleep(interval);
            if (Boolean.TRUE.equals(condition.get())) {
                logger.warn("retry succeeded after {} attempt(s): {}", attempt, description);
                return true;
            }
            logger.warn("retry attempt {}/{} failed for: {}", attempt, maxAttempts, description);
        }

View on GitHub (pinned to a22eb90246)