karatelabs/karate · error · Error (browser JS)

KARATE_ELEMENT_NOT_FOUND

KARATE_ELEMENT_NOT_FOUND

Error message

KARATE_ELEMENT_NOT_FOUND: {locator}

What it means

notFoundGuard injects a JS guard into generated locator expressions that throws an in-page Error with code KARATE_ELEMENT_NOT_FOUND when the target element is missing. It is applied to write/interaction actions where acting on a missing element is not harmless (unlike scroll or read actions, which stay null-tolerant).

Solutions

  1. Add a waitFor for the element before performing the action
  2. Verify the locator against the rendered DOM (log document queries)
  3. Retry with retry/retryUntil until the element appears
  4. Use null-tolerant reads or check existence first if the element is optional

Example fix

// before
driver.click("#submit"); // may throw KARATE_ELEMENT_NOT_FOUND
// after
driver.waitFor("#submit");
driver.click("#submit");
Defensive patterns

Strategy: try-catch

Validate before calling

Object exists = driver.script("!!document.querySelector('" + cssEscaped + "')");
if (!Boolean.TRUE.equals(exists)) {
    driver.waitFor("#submit");
}

Try / catch

try {
    driver.click("#submit");
} catch (RuntimeException e) {
    if (e.getMessage().contains("KARATE_ELEMENT_NOT_FOUND")) {
        driver.waitFor("#submit");
        driver.click("#submit");
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling an action API (click/input/clear etc. via js-built locators) whose element does not exist in the DOM at call time; the locator resolves to null inside the browser so the injected guard throws.

Common situations: Not waiting for SPA content to render, wrong locator after a UI redesign, element present only conditionally (popup shown on some flows), typos in css/xpath.

Related errors


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

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/driver/Locators.java:440

    public static final String ELEMENT_NOT_FOUND = "KARATE_ELEMENT_NOT_FOUND";

    /**
     * Generate a null guard for a resolved element variable, naming the locator.
     * <p>
     * Action JS must fail loudly on a null resolve. The two alternatives are both worse:
     * a silent no-op strands the caller with a downstream symptom far from the cause (an
     * empty field, an unfired event), and an unguarded deref reports a cryptic
     * "Cannot read properties of null" against generated source with no locator in it.
     * </p>
     * <p>
     * {@link #SCROLL_JS_FUNCTION} deliberately keeps its no-op-on-missing contract
     * instead — scrolling something absent is harmless, and that behavior is pinned by
     * a test. Read actions ({@link #textJs}, {@link #valueJs}, …) likewise stay
     * null-tolerant and return null.
     * </p>
     */
    private static String notFoundGuard(String var, String locator) {
        return " if (!" + var + ") throw new Error(\"" + ELEMENT_NOT_FOUND + ": " + escapeForJs(locator) + "\");";
    }

    /**
     * Generate JS to get element position.
     */
    public static String getPositionJs(String locator) {
        String js = "var e = " + selector(locator) + ";" +
                notFoundGuard("e", locator) +
                " var r = e.getBoundingClientRect();" +
                " var dx = window.scrollX; var dy = window.scrollY;" +
                " return { x: r.x + dx, y: r.y + dy, width: r.width, height: r.height }";
        return wrapInFunctionInvoke(js);
    }

    /**
     * Generate JS to focus an element with cursor at end.
     */
    public static String focusJs(String locator) {

View on GitHub (pinned to a22eb90246)