{"record":{"id":"4dd3c09e4cde3f9d","repo":"karatelabs/karate","slug":"varname-is-not-defined","errorCode":null,"errorMessage":"${varName} is not defined","messagePattern":"(.+?) is not defined","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/Interpreter.java","lineNumber":2609,"sourceCode":"\n    // The name-keyed tail of evalRefExpr, outlined so the slot fast path above\n    // stays small enough to inline reliably — an at-threshold hot method here\n    // flips whole benchmark rows run to run depending on JIT timing.\n    private static Object evalRefExprByName(Node node, CoreContext context) {\n        String varName = node.getText();\n        if (\"this\".equals(varName)) {\n            return context.getThisObject();\n        }\n        if (context.callArgs != null && \"arguments\".equals(varName)) {\n            JsArray a = context.argumentsForRead();\n            if (a != null) {\n                return a;\n            }\n            // arrow frame with no enclosing function — ordinary resolution\n        }\n        BindingSlot s = context.resolve(varName);\n        if (s == null) {\n            throw JsErrorException.referenceError(varName + \" is not defined\");\n        }\n        return context.readSlot(s, varName);\n    }\n\n    private static Object evalReturnStmt(Node node, CoreContext context) {\n        if (node.size() > 1) {\n            Object value = eval(node.get(1), context);\n            // `return somethingThatThrew()` — a callee that threw has already propagated its throw\n            // onto THIS context (JsFunctionNode.bindArgsAndExecute), and stopAndReturn would clear\n            // it and complete the function normally. The throw then no longer exists anywhere: a\n            // surrounding try/catch never fires, and the host-call boundary sees a clean return.\n            // Leave the context in its error state and let the exit unwind carry it.\n            if (context.isError()) {\n                return value;\n            }\n            return context.stopAndReturn(value);\n        } else {\n            // a valueless `return` completes with undefined, not null — the two are","sourceCodeStart":2591,"sourceCodeEnd":2627,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/Interpreter.java#L2591-L2627","documentation":"Thrown as a ReferenceError when an identifier cannot be resolved through any binding frame — no local slot, closure, or global carries the name. `evalRefExprByName` calls context.resolve and, if it returns null, reports the variable as undefined.","triggerScenarios":"Reading an undeclared identifier in Karate JS: typo in a variable name, using a variable defined in another feature/JS scope without passing it, or referencing a host object not registered in the engine context.","commonSituations":"Calling shared JS utilities that expect injected variables (karate, config values) which were not provided; misspelling camelCase names; assuming variables from one scenario leak into another.","solutions":["Fix the variable-name spelling or declare the variable before use (var/let/const).","Pass required values into embedded JS via the available context (e.g. karate.get / function arguments).","Verify the host object or global you expect is actually registered with the Karate JS engine in this scope."],"exampleFix":"// before\nvar total = price * qty; // price never defined\n// after\nvar price = 10;\nvar total = price * qty;","handlingStrategy":"try-catch","validationCode":"if (typeof price === 'undefined') throw new Error('price must be defined before use');","typeGuard":"function isDefined(v) { return typeof v !== 'undefined'; }","tryCatchPattern":"try { total = price * qty; } catch (e) { if (String(e).includes('is not defined')) { price = karate.get('price'); total = price * qty; } }","preventionTips":["Declare every variable before use","Check spelling/case of identifiers","Pass cross-feature values explicitly, don't rely on scope leakage"],"tags":["javascript","reference-error","undefined-variable"],"backgroundTag":"variable-not-defined","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}