karatelabs/karate · error · DriverException

element vanished during action after

Error message

element vanished during action after ${ELEMENT_ACTION_ATTEMPTS} re-resolve attempts: ${locator} | ${driverState}

What it means

During an element action, Karate checks existence then performs the action; if the element disappears in between, it re-resolves up to ELEMENT_ACTION_ATTEMPTS times with the configured retry interval between tries. If every re-resolve also fails, it throws with the attempt count, locator, driver state, and the last underlying error as cause.

Solutions

  1. Wait for app stability before acting: wait for the loading spinner to disappear or a stable container to exist.
  2. Re-run the action with retry-until semantics so a fresh attempt starts after the re-render settles.
  3. Target a stable ancestor/container rather than a node the framework replaces.
  4. Inspect the cause (lastError) in the exception to see whether a navigation or JS error removed the element.

Example fix

// before
driver.click('.list-item.active'); // re-rendered mid-action
// after
driver.waitForEnabled('.list-container');
driver.click('.list-container .list-item.active');
Defensive patterns

Strategy: retry

Validate before calling

// act only after the UI is stable (no spinners)
retryUntil(() -> !driver.exists(".spinner"));

Try / catch

try {
    driver.click(locator);
} catch (Exception e) {
    if (e.getMessage().contains("vanished during action")) {
        // cause holds the last underlying failure
        sleep(optionsRetryInterval);
        driver.click(locator);
    } else throw e;
}

Prevention

When it happens

Trigger: Element removed/re-rendered by the app (SPA re-render, animation, route change) between the exists() check and the action, persistently across all ELEMENT_ACTION_ATTEMPTS re-resolution rounds.

Common situations: React/Vue lists re-rendering while the test clicks; loading spinners replacing the target node; tests acting on elements during a transition; aggressive DOM cleanup (virtualized lists) unmounting off-screen nodes.

Related errors


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

Appendix: source

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

     * </p>
     */
    private Object elementAction(String locator, String js) {
        RuntimeException lastError = null;
        for (int i = 0; i < ELEMENT_ACTION_ATTEMPTS; i++) {
            retryIfNeeded(locator);
            try {
                return script(js);
            } catch (RuntimeException e) {
                if (!isElementVanished(e)) {
                    throw e;
                }
                lastError = e;
                logger.warn("element vanished between existence check and action, re-resolving ({}/{}): {}",
                        i + 1, ELEMENT_ACTION_ATTEMPTS, locator);
                sleep(options.getRetryInterval());
            }
        }
        throw new DriverException("element vanished during action after " + ELEMENT_ACTION_ATTEMPTS
                + " re-resolve attempts: " + locator + " | " + getDriverState(), lastError);
    }

    private static boolean isElementVanished(RuntimeException e) {
        return e.getMessage() != null && e.getMessage().contains(Locators.ELEMENT_NOT_FOUND);
    }

    // ========== Wait Methods ==========

    /**
     * Wait for an element to exist.
     */
    public Element waitFor(String locator) {
        return waitFor(locator, options.getTimeoutDuration());
    }

    /**
     * Wait for an element to exist with custom timeout.

View on GitHub (pinned to a22eb90246)