karatelabs/karate · error · JsErrorException (referenceError)

is not defined

Error message

${name} is not defined

What it means

This is Karate's embedded JS engine's ReferenceError, thrown when a bare identifier is looked up in the JS scope (getRefExprByName) and the context resolves it to CoreContext.NOT_FOUND. Karate throws it because evaluating an unknown name would otherwise silently yield null, hiding typos and missing variables. Unlike undefined property reads, an undefined standalone name is treated as a hard reference error, matching JavaScript semantics.

Solutions

  1. Check spelling of the identifier in the JS expression against the `def` statements and Scenario-Outline Examples column names.
  2. Add a `def` for the variable (or `* def name = karate.get('name', defaultValue)`) before the expression that uses it.
  3. If the variable comes from a called feature, ensure it is returned/assigned (e.g. `* def result = call read('x.feature')`) and reference `result.field`, not the raw name.
  4. Use `karate.get('name')` (which returns null) instead of a bare reference when absence is expected.

Example fix

// before (typo, variable never defined)
* match reponse.status == 200
// after
* def response = call read('helper.feature')
* match response.status == 200
Defensive patterns

Strategy: validation

Validate before calling

// Karate: check before use
* assert karate.get('myVar') != null || karate.fail('myVar is not defined')

Try / catch

// JS eval
try { doThing(myVar) } catch (e) { karate.log('reference error: ' + e); myVar = karate.get('myVar', defaultVal); }

Prevention

When it happens

Trigger: Evaluating a Karate JS expression that references a bare variable name that was never defined: a typo in a variable name (e.g. `reponse` instead of `response`), using a variable in a `match`/`assert`/`eval` before it is `def`'ed, or referencing a Scenario-Outline column that doesn't exist for the current row.

Common situations: Typos in feature files, variables defined in a Scenario but referenced in Background (or vice versa), forgetting `def` before use in `karate.call` arguments, renaming a variable without updating all match/assert expressions, calling a shared scope variable from a called feature that wasn't passed in.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at karate-js/src/main/java/io/karatelabs/js/PropertyAccess.java:657

                        throw SlotTable.tdzError(node.getText());
                    }
                    if (functionCall && context.root.bridge != null && v instanceof ExternalAccess ea) {
                        return externalConstructor(ea);
                    }
                    return v;
                }
            }
        }
        return getRefExprByName(node, context, functionCall);
    }

    // Name-keyed tail of getRefExpr, outlined to keep the slot fast path small
    // enough to inline reliably.
    private static Object getRefExprByName(Node node, CoreContext context, boolean functionCall) {
        String name = node.getText();
        Object result = context.getOrNotFound(name);
        if (result == CoreContext.NOT_FOUND) {
            throw JsErrorException.referenceError(name + " is not defined");
        }
        if (functionCall && context.root.bridge != null && result instanceof ExternalAccess ea) {
            return externalConstructor(ea);
        }
        return result;
    }

    private static JsConstructor externalConstructor(ExternalAccess ea) {
        return (c, args) -> ea.construct(args);
    }

    /**
     * Shared {@code REF_DOT_EXPR} resolution for both the value-only
     * ({@link #getRefDotExpr}) and call-site ({@link #getCallableRefDotExpr})
     * paths. Captures every AST shape (named dot, optional dot, optional
     * bracket, optional call), the external-bridge fallback on eval failure,
     * and the {@code ?.} short-circuit propagation in one place.
     * <p>

View on GitHub (pinned to a22eb90246)