Stirling-Tools/Stirling-PDF · error · StripeFunctionError
create-checkout-session returned neither client_secret nor U
Error message
create-checkout-session returned neither client_secret nor URL
What it means
Thrown by createCheckoutSession when the edge function reports success but provides neither an embedded client_secret nor a redirect URL. The function is expected to return at least one of client_secret (embedded Checkout) or url/portal_url (redirect), and a success response missing all of them is treated as malformed.
Source
Thrown at frontend/editor/src/portal/billing/stripe.ts:295
// redirect on completion. A redirect would reload the page, skip that finalize step, and
// make Stripe ignore onComplete entirely (console warns "redirect_on_completion: always").
redirect_on_completion: "never",
...(req.billingOwnerEmail
? { billing_owner_email: req.billingOwnerEmail }
: {}),
});
if (!res.success) {
throw new StripeFunctionError(
res.error ?? "create-checkout-session failed",
);
}
const alreadySubscribed = Boolean(res.already_subscribed);
const redirectUrl = alreadySubscribed
? (res.portal_url ?? null)
: (res.url ?? null);
const clientSecret = alreadySubscribed ? null : (res.client_secret ?? null);
if (!clientSecret && !redirectUrl) {
throw new StripeFunctionError(
"create-checkout-session returned neither client_secret nor URL",
);
}
return {
clientSecret,
redirectUrl,
alreadySubscribed,
};
}
/** Result of {@link createBundleStripeQuote} — the Stripe-issued quote handles. */
export interface BundleStripeQuote {
stripeQuoteId: string;
stripeQuoteNumber: string | null;
}
interface BundleStripeQuoteRequest {
teamId: number;View on GitHub (pinned to 9ef20dcab8)
Solutions
- Check the edge function: confirm every success path sets client_secret (embedded) or url/portal_url (redirect).
- Verify the Stripe Checkout Session was actually created and that client_secret is read from session.client_secret.
- For the already_subscribed branch, ensure billing portal creation populates portal_url.
- Catch and toast at the call site; this is an upstream contract bug, not a user error.
Example fix
// edge function — before
return json({ success: true });
// after
return json({
success: true,
client_secret: session.client_secret,
url: session.url,
}); Defensive patterns
Strategy: validation
Validate before calling
function isCheckoutResponseWellFormed(res: CheckoutResponse): boolean {
return Boolean(res.client_secret) || Boolean(res.url) || Boolean(res.portal_url);
}
// (defensive — the error indicates an upstream contract bug, but this guards UI code)
if (!isCheckoutResponseWellFormed(res)) {
throw new Error("Malformed checkout response from server.");
} Type guard
function hasCheckoutHandle(res: CheckoutResponse): res is CheckoutResponse & { client_secret?: string; url?: string; portal_url?: string } {
return Boolean(res.client_secret ?? res.url ?? res.portal_url);
} Try / catch
try {
const r = await createCheckoutSession(req);
// start embedded or redirect
} catch (e) {
if (e instanceof StripeFunctionError && /neither/i.test(e.message)) {
notifications.show({ message: "Checkout session could not be started. Try again.", color: "red" });
} else throw e;
} Prevention
- Ensure every success path in create-checkout-session sets client_secret or url/portal_url.
- Add a server-side contract test asserting the checkout response always carries a handle.
- Treat this error as an upstream bug — file an issue against the edge function.
When it happens
Trigger: create-checkout-session returns { success: true } but client_secret, url, and portal_url are all absent/null. Also fires when already_subscribed is true but portal_url was not provided.
Common situations: An edge function deploy returned success but forgot to include the Checkout handle; a Stripe Session was created but its client_secret/url weren't serialized; the already-subscribed branch didn't populate portal_url.
Related errors
- create-checkout-session failed
- Edge function ${name} returned no data
- create-payg-bundle-quote failed
- accept-payg-bundle-quote failed
- finalize-payg-bundle-invoice failed
AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13).
Data as JSON: /api/errors/a2e1c77e7cc5bb84.
Report an issue: GitHub.