karatelabs/karate · error · RuntimeException

JS exception

Error message

JS exception: {description}

What it means

Runtime.evaluate reported exceptionDetails containing an exception object whose description is available. Karate throws 'JS exception: <description>' carrying the page-side error (e.g. 'TypeError: x is not a function'). This means your in-page JavaScript threw, not a protocol failure.

Solutions

  1. Fix the JS expression — read the description for the exact TypeError/ReferenceError and line info
  2. Guard the expression: check the target exists before invoking (typeof fn === 'function')
  3. Wrap risky evaluation in try/catch inside the JS and return an error object you can assert on
  4. Ensure the page has loaded/initialized before evaluating (use waitUntil/waitFor before script)

Example fix

// before
Object v = driver.script("window.myApp.getData()"); // TypeError if myApp undefined
// after
Object v = driver.script("window.myApp ? window.myApp.getData() : null");
Defensive patterns

Strategy: try-catch

Validate before calling

// existence-check inside the expression before invoking
String guarded = "(typeof myApp !== 'undefined') ? myApp.getData() : null";

Try / catch

try { Object v = driver.script(expr); } catch (RuntimeException e) { if (e.getMessage().startsWith("JS exception:")) { // read description, fix expression or return fallback
  return null; } throw e; }

Prevention

When it happens

Trigger: driver.script(expression) where the evaluated expression throws at runtime in the page — undefined variables, calling non-existent functions, invalid syntax caught at evaluation, promises rejected without returnByValue-safe handling.

Common situations: Typos in the in-page API; running a script before the page defines expected globals; expression relying on DOM not yet present; browser-version-specific JS APIs missing in the test browser.

Related errors


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

Appendix: source

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

    }

    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() {
        return screenshot(false);

View on GitHub (pinned to a22eb90246)