karatelabs/karate · error · ParserException
#constructor is a reserved private name
Error message
#constructor is a reserved private name
What it means
`constructor` is reserved by the spec and cannot be used as a private class member name. While building the class's PrivateScope, classPrivateScand checks each member key and immediately rejects the literal name `#constructor`, regardless of member kind (field, method, getter, setter, static).
Solutions
- Rename the member, e.g. `#ctor` or `#init`, and update references
- Use the normal public `constructor(...)` method for construction logic — it cannot and should not be private
- If a private helper should run at construction, call it from the public constructor
Example fix
// before
class C { #constructor() { ... } }
// after
class C { #ctor() { ... } constructor() { this.#ctor(); } } Defensive patterns
Strategy: validation
Validate before calling
// Reject #constructor anywhere in class source: const hasReserved = /#constructor\b/.test(src);
Prevention
- Never name private members after reserved slots (constructor, prototype)
- Use conventional names like #ctor/#init for private construction helpers
- Run a quick grep for `#constructor` before shipping class code
When it happens
Trigger: Declaring any class member named `#constructor` — e.g. `class C { #constructor() {} }` or `class C { static #constructor = 1; }` — triggers this during privateNodeChecks.
Common situations: Confusion between the public `constructor` method and private naming schemes; generated/transformed code that prefixed all members with `#`; attempts to hide the constructor via privacy.
Related errors
- unexpected private name
- duplicate private name
- unexpected logical-assignment operator
- unexpected operator
- parser state: [ ]
AI-assisted analysis of karatelabs/karate@a22eb90246 (2026-09-12).
Data as JSON: /api/errors/007a3a504ec8521e.
Report an issue: GitHub.
Appendix: source
Thrown at karate-js/src/main/java/io/karatelabs/parser/JsParser.java:355
if (c.token.type == PRIVATE_NAME) {
key = c;
break;
}
String t = c.getText();
if ("get".equals(t)) {
kind = 1;
} else if ("set".equals(t)) {
kind = 2;
} else if ("static".equals(t)) {
kind |= 8;
}
}
if (key == null) {
continue;
}
String name = key.getText();
if ("#constructor".equals(name)) {
throw new ParserException("#constructor is a reserved private name");
}
if (names == null) {
names = new HashSet<>(4);
kinds = new HashMap<>(4);
}
Integer prior = kinds.put(name, kind);
// a get/set pair at the same placement is the sole legal duplicate
boolean accessorPair = prior != null && (prior & 8) == (kind & 8)
&& (prior & 4) == 0 && (kind & 4) == 0 && ((prior & 3) | (kind & 3)) == 3;
if (prior != null && !accessorPair) {
throw new ParserException("duplicate private name " + name + " in class body");
}
names.add(name);
}
return names == null ? parent : new PrivateScope(parent, names);
}
/**View on GitHub (pinned to a22eb90246)