karatelabs/karate · error · JsErrorException
is not defined
Error message
${key} is not defined What it means
In strict mode, assigning to a name that cannot be resolved to any binding is a ReferenceError — sloppy-mode implicit global creation is disabled. CoreContext.update throws `key + ' is not defined'` before it would call assignImplicitGlobal, because `strict` is set on the context.
Solutions
- Declare the variable first (let/var/const) before assigning.
- Fix the spelling of the identifier on the assignment's left side.
- Remove 'use strict' only as a last resort — prefer explicit declaration.
- Check that the variable isn't scoped to another script/evaluation that has ended.
Example fix
// before (strict mode) mode = "fast"; // after let mode = "fast";
Defensive patterns
Strategy: validation
Validate before calling
if (typeof targetVar === 'undefined') { throw new ReferenceError('declare targetVar before assigning'); } Type guard
function isDeclared(name) { try { eval(name); return true; } catch (e) { return false; } } Try / catch
try { engine.evalRaw(assignScript); } catch (JsErrorException e) { if (e.getMessage().endsWith("is not defined")) { /* declare the variable or fix the typo */ } else throw e; } Prevention
- Always declare variables before assigning.
- Watch for typos on assignment left-hand sides.
- Assume strict mode: never depend on implicit global creation.
When it happens
Trigger: update(key, value) resolving to null with strict=true — e.g. `undeclaredVar = 5` in strict-mode code, or a misspelled variable on the left side of an assignment / compound assignment.
Common situations: Typos in assignment targets; code written for sloppy mode run under strict mode ('use strict' or strict defaults); relying on accidental implicit globals across scripts that no longer exist.
Related errors
- ReferenceError: ' ' is not defined — did you mean `_. `?…
- ' ' is not a valid function name in strict mode
- ' ' is not a valid parameter name in strict mode
- duplicate parameter name
- ' ' is not a valid binding name in strict mode
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/9281892f6519ed14.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/CoreContext.java:564
update(key, value, null);
}
void update(String key, Object value, Node node) {
if (frameTable != null) {
int idx = frameTable.indexOf(key);
if (idx >= 0 && frame[idx] != SlotTable.UNDECLARED) {
updateSlot(idx, value, node);
return;
}
// undeclared: fall through — a pre-declaration write resolves an
// outer/global binding (or creates an implicit global), as today
}
BindingSlot s = resolve(key);
if (s == null) {
if (strict) {
// Strict mode forbids the sloppy implicit-global creation:
// assigning to an unresolvable name is a ReferenceError.
throw JsErrorException.referenceError(key + " is not defined");
}
assignImplicitGlobal(key, value, node);
return;
}
if (s.scope == BindScope.CONST && s.initialized) {
throw JsErrorException.typeError("assignment to constant: " + key);
}
// NamedEvaluation (§13.15.2): when RHS is an anonymous function expression and
// LHS is an IdentifierRef, set fn.name from the identifier. Mirrors the
// declare-path hook above. Skipped for already-named functions so e.g.
// `g = someNamedFn` does not clobber the original name.
if (value instanceof JsFunction fn && (fn.name == null || fn.name.isEmpty())) {
fn.name = key;
}
Object oldValue = s.value;
s.initialized = true;
// Unified write — works whether the Slot lives in this context's
// bindings, in capturedBindings, in an outer context, or in root.View on GitHub (pinned to a22eb90246)