karatelabs/karate · error

element vanished between existence check and action…

Error message

element vanished between existence check and action, re-resolving ({}/{}): {}

What it means

When performing an element action, the driver checks the element exists, resolves it, then runs the action JS — if the element is removed/re-rendered between check and action, the eval throws a 'vanished' error. The driver catches it, logs this warning with attempt count out of ELEMENT_ACTION_ATTEMPTS, re-resolves the locator, and retries after retryInterval. Only after exhausting all attempts does it throw DriverException with the driver state attached.

Solutions

  1. Wait for DOM stability before acting: waitFor the element, then wait for the triggering condition (network idle, spinner gone) before clicking.
  2. Use stable locators — target nodes that persist (containers/parents) rather than nodes the framework swaps out.
  3. Increase options retryInterval / retryCount so the built-in re-resolve attempts cover the re-render window.
  4. If it still fails after all attempts, read the DriverException message — it includes getDriverState() (current URL, frame) to diagnose which transition removed the element.

Example fix

// before
driver.click("div.results > div:nth-child(1) button"); // row re-rendered mid-click
// after
driver.waitFor("div.results");
driver.click("div.results div.row[data-id='42'] button.approve"); // stable data attribute
Defensive patterns

Strategy: retry

Validate before calling

driver.waitFor("div.results"); // element exists AND is stable before acting
driver.waitForUrl("**/list-loaded");

Try / catch

try {
    driver.click(locator);
} catch (Exception e) {
    // DriverException 'element vanished during action after N attempts':
    // message contains getDriverState() — check URL/frame to find the transition
    throw e;
}

Prevention

When it happens

Trigger: SPA frameworks (React/Vue) re-rendering and replacing DOM nodes, animations detaching elements, navigation triggered mid-action, or timers removing nodes (toasts, skeletons) between the exists-check and click/script call.

Common situations: Clicking buttons in fast-updating UIs, interacting with elements inside polling lists, CI slowness widening the race window, or tests that don't wait for network-driven DOM replacement to settle.


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

Appendix: source

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

     * </p>
     * <p>
     * Only the element-not-found marker is retried. Any other page-side JS error
     * propagates untouched — a real bug in the page under test must not be retried into
     * silence.
     * </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) {

View on GitHub (pinned to a22eb90246)