Skip to content

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

@proggeramlug

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions