Skip to content

node-fetch default import aliased away from 'fetch': r.status reads undefined because js_fetch_response_status is never emitted #10370

Description

@proggeramlug

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":

  1. 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.

  2. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions