With #10759 fixed (PR #10807), node-fetch@3.3.2 gets past the Function.prototype.call was called on a value that is not a function failure and hits the next one:
ReferenceError: Must call super constructor in derived class before accessing 'this'
or returning from derived constructor
raised inside node-fetch's real Headers.js. Pre-existing and separate from #10759 — reported rather than fixed, per that task's scope.
The shape
node-fetch's Headers is a derived class whose constructor calls super(...) and then returns a Proxy wrapping this:
export default class Headers extends URLSearchParams {
constructor(init) {
// ...normalise init into `result`...
super(result);
return new Proxy(this, { get(target, p, receiver) { /* ... */ } });
}
}
That is legal JavaScript and Node executes it without complaint. Perry raises the derived-constructor guard anyway.
Worth noting the guard is doing its job in general — this is not a claim that the check is wrong, but that something in this shape (a super() call followed by a constructor-return override, with a Proxy as the returned value) is not being recognised as having satisfied it.
Why it is worth attention beyond node-fetch
The constructor-return-override is not exotic. Returning a Proxy from a constructor is the standard way to give a class a dynamic property surface, and doing it from a derived class — after super() — is exactly what a subclass of a builtin must do. Anything wrapping a builtin this way is a candidate.
Reproduction
mkdir nf-probe && cd nf-probe
npm install node-fetch@3.3.2
# package.json: { "perry": { "compilePackages": ["node-fetch"] } }
# fixture.ts: import fetch from "node-fetch"; then a GET against a local node:http server
perry compile fixture.ts -o fixture && ./fixture
A package-independent reduction is the obvious first step and was not attempted: a derived class extending a builtin, calling super(), then returning new Proxy(this, {...}). If that reproduces, node-fetch is incidental.
Status
This is the second distinct defect in node-fetch's path, after #10759. Real-source node-fetch remains blocked, and its binding should not be removed until this is resolved. #10759's fix is correct and complete for what it claims — its gap test covers the same derived-class-plus-Proxy shape and passes byte-for-byte against Node — but the package needs both.
With #10759 fixed (PR #10807),
node-fetch@3.3.2gets past theFunction.prototype.call was called on a value that is not a functionfailure and hits the next one:raised inside node-fetch's real
Headers.js. Pre-existing and separate from #10759 — reported rather than fixed, per that task's scope.The shape
node-fetch'sHeadersis a derived class whose constructor callssuper(...)and then returns a Proxy wrappingthis:That is legal JavaScript and Node executes it without complaint. Perry raises the derived-constructor guard anyway.
Worth noting the guard is doing its job in general — this is not a claim that the check is wrong, but that something in this shape (a
super()call followed by a constructor-return override, with a Proxy as the returned value) is not being recognised as having satisfied it.Why it is worth attention beyond node-fetch
The constructor-return-override is not exotic. Returning a Proxy from a constructor is the standard way to give a class a dynamic property surface, and doing it from a derived class — after
super()— is exactly what a subclass of a builtin must do. Anything wrapping a builtin this way is a candidate.Reproduction
A package-independent reduction is the obvious first step and was not attempted: a derived class extending a builtin, calling
super(), then returningnew Proxy(this, {...}). If that reproduces, node-fetch is incidental.Status
This is the second distinct defect in node-fetch's path, after #10759. Real-source
node-fetchremains blocked, and its binding should not be removed until this is resolved. #10759's fix is correct and complete for what it claims — its gap test covers the same derived-class-plus-Proxy shape and passes byte-for-byte against Node — but the package needs both.