karatelabs/karate · error · JsErrorException
cannot access ' ' before initialization
Error message
cannot access '${node.getText()}' before initialization What it means
Thrown when reading a let/const binding in its temporal dead zone — after the slot exists (script has entered its scope) but before the initializer has executed. SlotTable.TDZ marks the un-initialized slot; the produced ReferenceError names the variable.
Solutions
- Move the `let`/`const` declaration above all code that reads it in the same scope.
- Rename the variable if a same-scope `var`/outer binding was shadowed unintentionally.
- Defer function calls that read the binding until after its initializer runs.
Example fix
// before console.log(x); let x = 1; // after let x = 1; console.log(x);
Defensive patterns
Strategy: validation
Validate before calling
if (typeof x === 'undefined' && declaredLater) throw new Error('x read before its let/const initialization'); Type guard
function isInitialized(fn) { try { fn(); return true; } catch (e) { return !String(e).includes('before initialization'); } } Try / catch
try { use(x); } catch (e) { if (String(e).includes('before initialization')) { /* defer or redeclare */ } } Prevention
- Declare let/const at the top of the scope
- Don't call functions that read bindings before their initializers run
- Replace TDZ-prone lazy patterns with functions returning values
When it happens
Trigger: Referencing a `let`/`const` variable earlier in the same scope than its declaration statement executes — e.g. using it inside a function called before the declaration line, or in its own initializer.
Common situations: Hoisting assumptions carried over from `var`; functions invoked during setup that touch bindings declared later; circular module-like top-level code in embedded scripts.
Related errors
- cannot access ' ' before initialization
- assignment to constant
- assignment to constant
- cannot access ' ' before initialization
- Unable to resolve global `this`
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/4c1ad448b76bade9.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/js/Interpreter.java:2583
}
String message = node.toStringError(rawMessage);
boolean authored = context.isErrorAuthored();
return new EngineException(message, null, errorName, jsMessage,
authored, authored ? errorThrown : null, authored ? context.getErrorAuthoredLine() : 0);
}
private static Object evalRefExpr(Node node, CoreContext context) {
if (node.getFirst().type == NodeType.FN_ARROW_EXPR) { // arrow function
return evalFnArrowExpr(node.getFirst(), context);
}
int slot = node.slot;
if (slot >= 0) {
Object[] frame = context.frame;
if (frame != null) {
Object v = frame[slot];
if (v != SlotTable.UNDECLARED) {
if (v == SlotTable.TDZ) {
throw SlotTable.tdzError(node.getText());
}
return v;
}
}
}
return evalRefExprByName(node, context);
}
// The name-keyed tail of evalRefExpr, outlined so the slot fast path above
// stays small enough to inline reliably — an at-threshold hot method here
// flips whole benchmark rows run to run depending on JIT timing.
private static Object evalRefExprByName(Node node, CoreContext context) {
String varName = node.getText();
if ("this".equals(varName)) {
return context.getThisObject();
}
if (context.callArgs != null && "arguments".equals(varName)) {
JsArray a = context.argumentsForRead();View on GitHub (pinned to a22eb90246)