Finally understood an issue I was encountering, that in my opinion is a bug and super confusing and deceptive.
SyntaxError: Private field must be declared in an enclosing class
The gist is the following: let's say you declared a class and have a private field (#somePrivateMethod) there.
class Example {
#somePrivateMethod(param1) {}
}
node --check reports 👌 so all good so far.
The issue arises when you write a very specific typo inside #somePrivateMethod, namely shadowing the private method parameters.
e.g.
class Example {
someInstanceMethod () {
this.#somePrivateMethod('test')
}
#somePrivateMethod(param1) {
// unintentional shadowing through typo or clanker
const param1 = '...'
}
}
node --check now will report the following:
tmp.js:3
this.#somePrivateMethod('test')
^
SyntaxError: Private field '#somePrivateMethod' must be declared in an enclosing class
at wrapSafe (node:internal/modules/cjs/loader:1806:18)
at checkSyntax (node:internal/main/check_syntax:76:3)
Node.js v26.3.0
The bug caused the Node.js parser to lose track of the definition of the private field #somePrivateMethod and breaking its static analysis.
To fix it, just do not inadvertently shadow/redeclare vars with the same name as the function arguments:
class Example {
someInstanceMethod () {
this.#somePrivateMethod('test')
}
#somePrivateMethod(param1) {
// no shadowing/redeclaration
const renamed = '...'
}
}
This is extremely confusing, because it should be SyntaxError: Identifier 'param1' has already been declared.
Noticed that this only happens for #private methods.
Interestingly, the parser reports the error correctly, if the private method is not called!
class Example {
#somePrivateMethod(param1) {
const param1 = '...'
}
}
tmp.js:3
const param1 = '...'
^
SyntaxError: Identifier 'param1' has already been declared
at wrapSafe (node:internal/modules/cjs/loader:1806:18)
at checkSyntax (node:internal/main/check_syntax:76:3)
Node.js v26.3.0
This would have been the expected reporting.
Chris