karatelabs/karate · error · EngineException

<js error message from context>

Error message

<js error message from context>

What it means

The JS interpreter finished (or unwound) a program while the evaluation context carried an error state; it converts that pending error into a thrown exception via errorAsException(context, child). The message is whatever the underlying JS error produced, so this is the generic surfacing point for uncaught JS errors during program evaluation.

Solutions

  1. Read the embedded `<js error message>` to identify the original JS failure (undefined variable, TypeError, thrown value).
  2. Wrap risky JS in try/catch inside the script itself.
  3. Fix the referenced line/symbol in the JS snippet or feature step that produced the error.

Example fix

// before (JS)
var x = notDefined + 1;

// after (JS)
var x = (typeof notDefined !== 'undefined' ? notDefined : 0) + 1;
Defensive patterns

Strategy: try-catch

Try / catch

// inside JS snippets
try {
  var result = riskyCall();
} catch (e) {
  console.log('js failed: ' + e);
  result = null;
}

Prevention

When it happens

Trigger: Executing a JS program where a statement throws (runtime TypeError, ReferenceError, or a thrown user error) at top-level statement scope in evalProgram; context.isError() is true after evaluating a child statement.

Common situations: Calling an undefined function in a JS expression block; throwing custom errors from test scripts; type errors in match/eval-driven JS during scenario runs.

Related errors


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

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/Interpreter.java:2512

        // convention so host code that loads a script consisting of just a
        // function definition can use the eval result directly.
        Object progResult = null;
        boolean anyNonDecl = false;
        Object lastFnDecl = null;
        for (int i = 0, n = node.size(); i < n; i++) {
            Node child = node.get(i);
            if (child.isEof()) {
                break;
            }
            if (isFunctionDeclarationStatement(child)) {
                String fnName = child.getFirst().get(1).getText();
                lastFnDecl = context.get(fnName);
                continue;
            }
            progResult = eval(child, context);
            anyNonDecl = true;
            if (context.isError()) {
                throw errorAsException(context, child);
            }
        }
        return anyNonDecl ? progResult : lastFnDecl;
    }

    /**
     * Convert a context left in JS-error state ({@link CoreContext#isError()}) into the host-facing
     * {@link EngineException} — the single conversion that makes an uncaught JS {@code throw} look
     * JS-native to a Java caller (structured {@code jsErrorName} + {@code jsMessage}). Applied at the
     * top-level statement boundary ({@link #evalProgram}) and at the host-invocation boundary
     * ({@link JsFunctionNode#call} when a host calls a JS function directly, with no JS caller context),
     * so {@code someFn.call(null, args)} surfaces an uncaught throw exactly like {@code engine.eval}.
     *
     * @param node frames the host-facing (logging) message; the structured {@code jsErrorName}/
     *             {@code jsMessage} are framing-independent
     */
    static EngineException errorAsException(CoreContext context, Node node) {
        Object errorThrown = context.getErrorThrown();

View on GitHub (pinned to a22eb90246)