Skip to content

Bug Report: @polymarket/clob-client-v2ensureBuilderFeeRateCached breaks browser-based order creation #51

@kzndotsh

Description

@kzndotsh

Summary

The V2 SDK (@polymarket/clob-client-v2@1.0.2) makes a direct HTTP request to GET /fees/builder-fees/<builderCode> during createOrder and createMarketOrder. This endpoint returns 404 with no CORS headers, causing order creation to fail entirely in browser environments.

Affected versions

  • @polymarket/clob-client-v2@1.0.1 and 1.0.2
  • @polymarket/clob-client-v2@1.0.0 is not affected (method doesn't exist)

Reproduction

  1. Create a ClobClient in a browser context (e.g. Next.js client component)
  2. Call client.createOrder() or client.createMarketOrder() with builderCode on the order object (as documented in the V2 migration guide)
  3. The SDK internally calls ensureBuilderFeeRateCached(builderCode) which fetches https://clob.polymarket.com/fees/builder-fees/<builderCode>
  4. The endpoint returns HTTP 404 with no Access-Control-Allow-Origin header
  5. The browser blocks the response (CORS), the SDK throws, and order creation aborts

Root cause

ensureBuilderFeeRateCached (added in 1.0.1/1.0.2) calls this.get() against /fees/builder-fees/<code> to cache builder fee rates for fee-adjusted amount calculations. Two problems:

  1. The endpoint returns 404 — it either doesn't exist yet in V2 production or isn't deployed
  2. No CORS headers on the 404 response — even if the endpoint existed, browser-based clients would be blocked

The method is called unconditionally whenever builderCode is present on the order, regardless of whether builderConfig is set on the client. There's no try-catch around it — the error propagates and kills the entire createOrder/createMarketOrder call.

Impact

Any builder using the SDK in a browser (React/Next.js apps, browser extensions, etc.) cannot place orders with builder attribution. This is the documented V2 pattern — passing builderCode per-order as shown in the migration guide and Builder Program docs.

Server-side usage is unaffected (no CORS restrictions).

Workaround

Pre-populate the SDK's internal builderFeeRates cache after client creation to prevent the HTTP fetch:

const client = new ClobClient({ host, chain, signer, creds, ... });
// Prevent CORS-blocked fetch to /fees/builder-fees
const code = process.env.NEXT_PUBLIC_POLY_BUILDER_CODE;
if (code && (client as any).builderFeeRates) {
  (client as any).builderFeeRates[code] = { maker: 0, taker: 0 };
}

Alternatively, pin to @polymarket/clob-client-v2@1.0.0 which doesn't have the method.

Suggested fix

In the SDK, either:

  • Wrap ensureBuilderFeeRateCached in a try-catch so it fails silently (fee adjustment is optional — platform fees are handled at match time)
  • Add CORS headers to GET /fees/builder-fees/<code>
  • Skip the fetch when running in a browser context (typeof window !== 'undefined')

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