Skip to content

fix(server-sdk): preserve Request headers on x402 retry - #80

Open
snuff12 wants to merge 1 commit into
ChainSafe:mainfrom
snuff12:snuff12/preserve-request-retry-headers
Open

snuff12 wants to merge 1 commit into
ChainSafe:mainfrom
snuff12:snuff12/preserve-request-retry-headers

Conversation

@snuff12

@snuff12 snuff12 commented Nov 1, 2026

Copy link
Copy Markdown

What changed and why

Fixes #79

The first request can carry Request-owned authorization/tenant headers, but the paid retry currently replaces them with a header list constructed only from init.headers. Inherit input.headers when the input is a Request and init.headers is undefined, then set X-PAYMENT on a copy. Explicit overrides, including empty header collections, continue to replace the inherited header list.

Add native-fetch loopback regressions and a patch changeset for @chainsafe/x402-server-sdk.

Approved plan and scope

The operator approved the written research/plan before implementation and explicitly requested issue/PR publication. Relevant approved plan slice:

  1. Keep the initial fetch and payer/requirement selection unchanged.
  2. On the paid retry, use explicit init.headers when defined; otherwise inherit headers from a Request input.
  3. Copy the effective headers and set the encoded X-PAYMENT header.
  4. Test native Request inheritance, explicit/empty replacements, input immutability, and unchanged bypass paths.
  5. Add a package patch changeset and run workspace build, typecheck, lint, and tests on Node 24.

Acceptance criteria are recorded in the linked issue. This is a header-only fix. Consumed Request bodies and ReadableStream replay remain subject to the existing documented exclusions.

Validation

On Node 24.22.2 (matching .nvmrc):

pnpm build
pnpm typecheck
pnpm lint
pnpm test

All passed: 133 workspace tests, including 32 SDK tests / 22 fetch tests. Seven header-regression cases fail on the original source and pass after the fix. Tests exercise native fetch against a loopback merchant with fixture-only authorization, without live Canton traffic. Two fresh independent Codex reviewers reviewed the final commit and ran their own checks before publication.

Operational impact

No environment variables, secrets, config keys, schemas, ports, dependencies, or deployment steps change. No public type/signature changes. Paid retries retain effective caller headers as native fetch semantics require; callers providing explicit init.headers retain full-replacement behavior.

Assumptions and scope

Request detection uses the runtime's native Request constructor. Cross-realm Request detection is not introduced. The only additional files are regression tests and the required release changeset.

AI-assisted code and PR description, prepared with Codex following chainsafe-research-plan-implement; operator-approved plan as quoted above. All PR commits are SSH-signed. Maintainer review and merge remain with the project.

@dimartiro

Copy link
Copy Markdown
Contributor

@dhyaniarun1993 would u like to take a look as well?

@dhyaniarun1993

Copy link
Copy Markdown
Member

@dhyaniarun1993 would u like to take a look as well?

Yea, I will review this today.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

createX402Fetch drops Request-owned headers on the paid retry

3 participants