Skip to content

Stripe SDK: stripe.products.create throws 'replace is not a function' (request dispatch, flat body) after #4831 #4841

Description

@proggeramlug

Summary

After #4831 fixed Stripe SDK method dispatch, calling a Stripe SDK method (e.g. stripe.products.create({ name })) now reaches the request layer but throws TypeError: replace is not a function — even for a flat request body. So Stripe requests still fail end-to-end on Perry.

Repro (verified on Linux; makes a real Stripe test-mode call)

import Stripe from "stripe";
const s = new Stripe(process.env.STRIPE_SECRET_KEY as string, {});
try {
  const p = await s.products.create({ name: "Perry Repro DELETE" });
  console.log("OK product id:", p.id);
} catch (e: any) {
  console.log("ERR:", e?.name, e?.message);
  console.log("STACK:", e?.stack);
}
STRIPE_SECRET_KEY=sk_test_... perry compile striperepro.ts -o striperepro && ./striperepro

Actual (bug)

ERR: TypeError replace is not a function
STACK: TypeError: replace is not a function
    at <anonymous>

(e.stack collapses to at <anonymous> — see note below; a real JS stack would help a lot here.)

Localization done so far

Stripe (cjs build) has exactly 5 .replace( sites; I instrumented the three that a flat products.create would hit and none of them executed before the throw:

  • StripeResource.js _joinUrlPartsparts.join('/').replace(...) (path build) — never logged
  • utils.js queryStringifyRequestDataqs.stringify(data,...).replace(...) (body encode) — never logged
  • utils.js makeURLInterpolatorstr.replace(...) (path interpolation) — never logged

So the failing .replace is upstream of path-building and body-encoding — i.e. in the request dispatch (stripeMethodmakeRequest_request), header/User-Agent setup, or a transitive dependency reached before those. The receiver is a non-string value whose .replace is undefined (a TypeError: ... is not a function, not Cannot read properties of undefined).

This may share a root cause with #4831 (cross-module extend dispatch) — the dispatched method may receive an argument/this of the wrong type, so a value the SDK expects to be a string is something else.

Secondary (separate, filed as #4840)

qs.stringify on nested bodies throws Constructor WeakMap requires 'new' — will block subscription/checkout calls (nested items/line_items) once this replace issue is resolved.

Ask

A readable JS stack for uncaught TypeErrors in compiled binaries would make this trivial to localize (currently Error.stack is just at <anonymous>). Otherwise, reproducing the stripeMethod/extend request path with a flat body should surface it.

Environment

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