Skip to content

401 retry fails for fetch(new Request(...)) with a body (stream consumed) #9

Description

@melvincarvalho

Follow-up surfaced during #6 review.

Problem

Both fetch interceptors (src/nip98-interceptor.js and src/injected.js) retry a failed (401) request using the same url argument they were originally called with. When the page calls fetch(new Request(url, { body: ... })), that Request has a ReadableStream body that is consumed on the first fetch. The retry then receives a Request with an empty/locked body and rejects with a TypeError — the caller sees a rejected fetch instead of the original 401 response.

Scope

  • Only affects fetch(new Request(...)) form with a non-empty body.
  • Does NOT affect fetch(url, { method, body }) form — that form passes a fresh body on each call.
  • Most Solid code uses the second form, which is why this hasn't been observed.

Proposed fix

At the top of the fetch wrapper, if input instanceof Request (or cross-realm equivalent — see #8), clone the Request immediately and keep the clone for potential retry. When retrying, use the clone (or a freshly constructed Request from the clone) so the body stream is fresh.

Consider headers/signal/method propagation during cloning.

Scope note

Not fixing in #6 because that PR is scoped to the auth-overwrite bug. This is a separate correctness issue for a different fetch input shape.

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