Problem
Binding a node-fetch default import to a name other than fetch loses the response's .status (and, presumably, its other property reads): the awaited value's properties don't resolve.
import nodeFetch from "node-fetch"; // any name other than `fetch`
const r = await nodeFetch(u);
console.log(typeof r, r.status); // status is undefined
vs. the same call bound to the literal name fetch, which works.
Why this is a different bug from the node-fetch SIGSEGV
Turnloop lane P11's report (docs/turnloop/p11-report.md) isolated two defects that read identically from JS as "fetch is broken":
-
Handle-encoding SIGSEGV (P8's defect 1). import 'node-fetch' bound to the literal name fetch set uses_fetch, which linked two fetch implementations into the same binary at once — the (now-deleted) perry-ext-fetch wrapper crate, using bare-double handles from its own six per-type counters starting at 1, and perry-stdlib's fetch, using NaN-boxed POINTER_TAG handles from one shared band. A value minted by one and read by the other is a small integer dereferenced as a pointer. P11 fixed this by deleting the duplicate: perry-ext-fetch and its rows in well_known_bindings.toml are gone, so node-fetch always resolves to perry-stdlib's fetch now. This bug is closed by that change.
-
This bug, which P11's fix did not touch. It reproduces identically on the pre-P11 base commit and on the P11 branch. Bound to any name other than fetch, HIR does not set uses_fetch. On the P11 branch, nm on the linked binary confirms there is exactly one, correct fetch implementation present — js_fetch_with_options sits at 0x944c71, immediately next to js_fetch_handle_kind at 0x9442c6, both perry-stdlib's symbols — but js_fetch_response_status is not in the binary at all. Codegen lowers the call (nodeFetch(u)) but not the property read (r.status), so .status falls through to a generic property lookup on a handle value, which reads back undefined.
P8 had seen the undefined symptom without diagnosing it: "may be the bare-number handle above, or it may be that the awaited value's type is not proven to be a Response at the property site" — both hypotheses were right, for different programs. P11 separated the two by fixing the first; this issue is the second, and it is still open on both arms.
What would fix it
This looks like an alias-tracking gap in HIR/codegen: whatever type-proof lets r.status lower to a call to js_fetch_response_status (instead of falling through to a generic property lookup) appears to key off the literal binding name fetch, or off uses_fetch, rather than off the awaited call's actual proven return type. It's likely the same root cause as uses_fetch not being set for an aliased default import — worth checking whether fixing that alone makes the property-read proof follow the binding regardless of its name.
Problem
Binding a
node-fetchdefault import to a name other thanfetchloses the response's.status(and, presumably, its other property reads): the awaited value's properties don't resolve.vs. the same call bound to the literal name
fetch, which works.Why this is a different bug from the node-fetch SIGSEGV
Turnloop lane P11's report (
docs/turnloop/p11-report.md) isolated two defects that read identically from JS as "fetch is broken":Handle-encoding SIGSEGV (P8's defect 1).
import 'node-fetch'bound to the literal namefetchsetuses_fetch, which linked two fetch implementations into the same binary at once — the (now-deleted)perry-ext-fetchwrapper crate, using bare-double handles from its own six per-type counters starting at 1, andperry-stdlib's fetch, using NaN-boxed POINTER_TAG handles from one shared band. A value minted by one and read by the other is a small integer dereferenced as a pointer. P11 fixed this by deleting the duplicate:perry-ext-fetchand its rows inwell_known_bindings.tomlare gone, sonode-fetchalways resolves to perry-stdlib's fetch now. This bug is closed by that change.This bug, which P11's fix did not touch. It reproduces identically on the pre-P11 base commit and on the P11 branch. Bound to any name other than
fetch, HIR does not setuses_fetch. On the P11 branch,nmon the linked binary confirms there is exactly one, correct fetch implementation present —js_fetch_with_optionssits at0x944c71, immediately next tojs_fetch_handle_kindat0x9442c6, both perry-stdlib's symbols — butjs_fetch_response_statusis not in the binary at all. Codegen lowers the call (nodeFetch(u)) but not the property read (r.status), so.statusfalls through to a generic property lookup on a handle value, which reads backundefined.P8 had seen the
undefinedsymptom without diagnosing it: "may be the bare-number handle above, or it may be that the awaited value's type is not proven to be aResponseat the property site" — both hypotheses were right, for different programs. P11 separated the two by fixing the first; this issue is the second, and it is still open on both arms.What would fix it
This looks like an alias-tracking gap in HIR/codegen: whatever type-proof lets
r.statuslower to a call tojs_fetch_response_status(instead of falling through to a generic property lookup) appears to key off the literal binding namefetch, or offuses_fetch, rather than off the awaited call's actual proven return type. It's likely the same root cause asuses_fetchnot being set for an aliased default import — worth checking whether fixing that alone makes the property-read proof follow the binding regardless of its name.