Skip to content

Fix HTTPFacilitatorClient not following 308 redirects#1813

Open
ayushozha wants to merge 1 commit intocoinbase:mainfrom
ayushozha:fix/http-facilitator-client-follow-redirects
Open

Fix HTTPFacilitatorClient not following 308 redirects#1813
ayushozha wants to merge 1 commit intocoinbase:mainfrom
ayushozha:fix/http-facilitator-client-follow-redirects

Conversation

@ayushozha
Copy link

Summary

Fixes #1692

The x402.org/facilitator/supported endpoint returns HTTP 308 before resolving to 200. HTTPFacilitatorClient did not normalize the base URL or explicitly request redirect following, causing syncFacilitatorOnStart to silently fail in some JS runtimes. When no supported payment kinds are loaded, the middleware passes all requests through as 200 instead of returning 402.

Root cause

$ curl -s "https://x402.org/facilitator/supported" -w "\n%{http_code}" -o /dev/null
308

$ curl -sL "https://x402.org/facilitator/supported" -w "\n%{http_code}" -o /dev/null
200

While the Fetch API default redirect mode is "follow", not all JS runtimes (Node.js versions, edge runtimes, polyfills) handle 308 redirects consistently — especially for POST requests where method preservation is required by spec but not always implemented.

Changes

File Change
typescript/packages/core/src/http/httpFacilitatorClient.ts Strip trailing slashes from URL in constructor; add redirect: "follow" to all fetch calls
typescript/packages/core/test/unit/http/httpFacilitatorClient.test.ts Add URL normalization tests + redirect option propagation tests
typescript/.changeset/fix-facilitator-redirect.md Changeset fragment

Test plan

  • URL normalization: trailing slash stripped, multiple slashes stripped, clean URL unchanged, default URL correct
  • Redirect option: redirect: "follow" passed on getSupported(), verify(), settle()
  • Endpoint URL construction correct after normalization
  • All 15 tests pass (7 existing + 8 new)

cc @CarsonRoscoe @andichen0420

The x402.org/facilitator/supported endpoint returns HTTP 308 before
resolving to 200. HTTPFacilitatorClient did not normalize the base URL
or explicitly request redirect following, causing syncFacilitatorOnStart
to silently fail in some runtimes. When no supported payment kinds are
loaded, the middleware passes all requests through as 200 instead of 402.

- Strip trailing slashes from facilitator URL in constructor to prevent
  unnecessary 308 redirects from trailing-slash normalization
- Explicitly set redirect: "follow" on all fetch calls (verify, settle,
  getSupported) for cross-runtime compatibility
- Add tests for URL normalization and redirect option propagation

Closes coinbase#1692
@cb-heimdall
Copy link

🟡 Heimdall Review Status

Requirement Status More Info
Reviews 🟡 0/1
Denominator calculation
Show calculation
1 if user is bot 0
1 if user is external 0
2 if repo is sensitive 0
From .codeflow.yml 1
Additional review requirements
Show calculation
Max 0
0
From CODEOWNERS 0
Global minimum 0
Max 1
1
1 if commit is unverified 1
Sum 2

@vercel
Copy link

vercel bot commented Mar 25, 2026

@ayushozha is attempting to deploy a commit to the Coinbase Team on Vercel.

A member of the Team first needs to authorize it.

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

@x402/express v2.6.0 middleware silently passes through requests (returns 200 instead of 402) with x402.org facilitator

2 participants