karatelabs/karate · error

JS exception for: ->

Error message

JS exception for: {} -> {}

What it means

When Runtime.evaluate returns exceptionDetails, CdpDriver throws RuntimeException("JS exception: <description>") using the exception object's description. This means the JavaScript expression executed via driver.script()/eval threw an uncaught error in the browser. The library surfaces the browser-side message so the caller can see the actual JS failure rather than a generic CDP error.

Solutions

  1. Read the description after 'JS exception: ' — it contains the browser's actual error (line number, message); fix the JS accordingly.
  2. Guard the expression: wrap risky JS in try/catch inside the expression, or check typeof before dereferencing (e.g. "window.foo ? foo.bar : null").
  3. Ensure the correct frame is active (switchFrame) before evaluating — the symbol may exist only in another frame.
  4. Wait for the page to be ready (waitForUrl / implicit waits) so page globals exist before eval.

Example fix

// before
String title = driver.script("document", "_.title || missingGlobal.name");
// after
String title = driver.script("document", "typeof missingGlobal !== 'undefined' ? missingGlobal.name : _.title");
Defensive patterns

Strategy: try-catch

Validate before calling

// before eval, ensure the symbol exists
Boolean ok = (Boolean) driver.script("window", "typeof paymentConfig !== 'undefined'");
if (!Boolean.TRUE.equals(ok)) { driver.waitFor("#config-loaded"); }

Try / catch

try {
    Object result = driver.script("document", expr);
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("JS exception: ")) {
        // browser-side JS threw: fix expr or wait for page readiness
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling script(html, expression) or CdpDriver.script() with a JS expression that throws at evaluation time — e.g. referencing an undefined variable, calling a method on null/undefined, or JSON.parse of invalid data. The description branch is taken when exceptionDetails.exception.description is present (typical for Error/TypeError objects).

Common situations: Typos in injected JS, page scripts not yet defining a global the expression relies on, evaluating in the wrong frame/context where the expected object doesn't exist, or Chrome's stricter JS engine rejecting code that worked elsewhere.

Related errors


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

Appendix: source

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

        return frameContexts.get(currentFrame.id);
    }

    private Object extractJsValue(CdpResponse response, String expression) {
        if (response.isError()) {
            String message = response.getErrorMessage();
            if (message != null && message.contains("Object reference chain is too long")) {
                logger.debug("script result not serializable, returning null: {}", truncate(expression, 100));
                return null;
            }
            logger.warn("JS error for expression: {}", truncate(expression, 100));
            throw new RuntimeException("JS error: " + response.getError());
        }
        Object exceptionDetails = response.getResult("exceptionDetails");
        if (exceptionDetails != null) {
            // Try to get detailed error message from exception object
            String description = response.getResultAsString("exceptionDetails.exception.description");
            if (description != null && !description.isEmpty()) {
                logger.warn("JS exception for: {} -> {}", truncate(expression, 100), truncate(description, 200));
                throw new RuntimeException("JS exception: " + description);
            }
            // Fall back to text (usually just "Uncaught")
            String text = response.getResultAsString("exceptionDetails.text");
            logger.warn("JS exception for: {} -> {}", truncate(expression, 100), text);
            throw new RuntimeException("JS exception: " + text);
        }
        Object value = response.getResult("result.value");
        logger.trace("script result: {}", value);
        return value;
    }

    // ========== Screenshot ==========

    /**
     * Take screenshot and return PNG bytes.
     */
    public byte[] screenshot() {

View on GitHub (pinned to a22eb90246)