{"record":{"id":"8c9c42b58687945f","repo":"karatelabs/karate","slug":"unexpected-private-name-node-gettext","errorCode":null,"errorMessage":"unexpected private name ${node.getText()}","messagePattern":"unexpected private name (.+?)","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/Interpreter.java","lineNumber":3358,"sourceCode":"            case ASSIGN_EXPR -> evalAssignExpr(node, context);\n            case BLOCK -> evalBlock(node, context);\n            case BREAK_STMT -> evalBreakStmt(node, context);\n            case CONTINUE_STMT -> evalContinueStmt(node, context);\n            case LABELLED_STMT -> evalLabelledStmt(node, context);\n            case DELETE_EXPR -> evalDeleteExpr(node, context);\n            case EXPR -> evalExpr(node, context);\n            case EXPR_LIST -> evalExprList(node, context);\n            case LIT_EXPR -> evalLitExpr(node, context);\n            case FN_EXPR -> evalFnExpr(node, context);\n            case FN_ARROW_EXPR -> evalFnArrowExpr(node, context);\n            case FN_CALL_EXPR -> chainStepResult(evalFnCall(node, context, false), node);\n            case FN_TAGGED_TEMPLATE_EXPR -> chainStepResult(evalFnTaggedTemplate(node, context), node);\n            case FOR_STMT -> evalForStmt(node, context);\n            case IF_STMT -> evalIfStmt(node, context);\n            case INSTANCEOF_EXPR -> evalInstanceOfExpr(node, context);\n            case IN_EXPR -> evalInExpr(node, context);\n            // only reachable in error-recovery mode, which skips the early-error walk\n            case PRIVATE_NAME_EXPR -> throw JsErrorException.syntaxError(\n                    \"unexpected private name \" + node.getText());\n            case LOGIC_EXPR -> evalLogicExpr(node, context);\n            case LOGIC_AND_EXPR -> evalLogicAndExpr(node, context);\n            case LOGIC_NULLISH_EXPR -> evalLogicNullishExpr(node, context);\n            case LOGIC_BIT_EXPR -> evalLogicBitExpr(node, context);\n            case LOGIC_TERN_EXPR -> evalLogicTernExpr(node, context);\n            case MATH_ADD_EXPR -> evalMathAddExpr(node, context);\n            case MATH_EXP_EXPR -> Terms.exp(lhsOperand(node, context), rhsOperand(node, context), context);\n            case MATH_MUL_EXPR -> evalMathMulExpr(node, context);\n            case MATH_POST_EXPR -> evalMathPostExpr(node, context);\n            case MATH_PRE_EXPR -> evalMathPreExpr(node, context);\n            case NEW_EXPR -> evalNewExpr(node, context);\n            case PAREN_EXPR -> eval(node.get(1), context);\n            case CLASS_EXPR -> evalClassExpr(node, context);\n            case SUPER_EXPR -> evalSuperBase(context); // base for super.x / super[x] reads\n\n            case PROGRAM -> evalProgram(node, context);\n            case REF_EXPR -> evalRefExpr(node, context);","sourceCodeStart":3340,"sourceCodeEnd":3376,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/Interpreter.java#L3340-L3376","documentation":"Karate's parser produces PRIVATE_NAME_EXPR nodes for `#name` private-class-field syntax, but a normal parse should reject invalid private-name usage during the early-error walk. Hitting this at evaluation time means error-recovery mode skipped that walk, and the interpreter encountered a private name it cannot resolve. It is a defensive syntax error rather than a runtime data problem.","triggerScenarios":"Evaluating JS containing a `#privateName` reference outside valid class private-field context (e.g. `obj.#x` or a bare `#x`) when parsing runs in error-recovery mode that defers early errors to evaluation.","commonSituations":"Typing `#` prefixed identifiers in embedded JS (also colliding with Karate's own `#variable` placeholder syntax getting into JS); partial/invalid code evaluated incrementally by tooling; copy-paste of class private-field code into non-class scope.","solutions":["Remove or correct the `#name` reference; private fields are only valid inside class bodies declaring that field","Check whether a Karate `#placeholder` leaked un-substituted into JS and quote or escape it appropriately","Fix surrounding syntax errors so the early-error walk runs and reports the real location before evaluation"],"exampleFix":"// before\nconst v = obj.#secret; // invalid outside class\n// after\nclass C { #secret = 1; get secret() { return this.#secret; } }\nconst v = new C().secret;","handlingStrategy":"try-catch","validationCode":"// lint JS before eval: flag /(^|[^\\w$])#[A-Za-z_$]/ outside class bodies\nconst badPrivate = /(^|[^\\w$.])#\\s*[A-Za-z_$]/.test(jsSource) && !/class[\\s{]/.test(jsSource);","typeGuard":null,"tryCatchPattern":"try { karate.eval(js); } catch (e) { if (String(e).includes('unexpected private name')) { /* surface a syntax-fix hint to the author */ } }","preventionTips":["Do not use #identifiers in embedded Karate JS — # is Karate placeholder syntax","Use private fields only inside class bodies that declare them","Lint embedded JS snippets before evaluation to catch private-name syntax early"],"tags":["javascript","syntax-error","private-fields"],"backgroundTag":"invalid-identifier-format","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"}