Stirling-Tools/Stirling-PDF · error · StripeFunctionError
create-checkout-session failed
Error message
create-checkout-session failed
What it means
Fallback thrown by createCheckoutSession when the edge function returns res.success === false but no res.error field. It means the function explicitly reported failure yet omitted an explanation, so the client substitutes a generic message.
Source
Thrown at frontend/editor/src/portal/billing/stripe.ts:285
export async function createCheckoutSession(
req: CheckoutSessionRequest,
): Promise<CheckoutSession> {
const res = await invoke<CheckoutResponse>("create-checkout-session", {
team_id: req.teamId,
currency: req.currency ?? "usd",
success_url: req.successUrl,
cancel_url: req.cancelUrl,
// The portal drives an in-page onComplete handler (the checkout modal stays open to
// finalise activation + nudge the linked instance), so tell the edge function not to
// 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,
};View on GitHub (pinned to 9ef20dcab8)
Solutions
- Open the create-checkout-session edge function logs in the Supabase dashboard to find the real failure branch.
- Ensure every failure branch in the function returns { success: false, error: '<detail>' }.
- Verify Stripe secret key + price/price-tier config the function reads.
- Catch StripeFunctionError at the call site and surface a user-facing message; retry after fixing config.
Example fix
// edge function — before
return new Response(JSON.stringify({ success: false }), { status: 200 });
// after
return new Response(
JSON.stringify({ success: false, error: 'Stripe price not found for currency' }),
{ status: 200, headers: { 'Content-Type': 'application/json' } },
); Defensive patterns
Strategy: try-catch
Type guard
function isCheckoutFailure(res: CheckoutResponse): res is CheckoutResponse & { success: false } {
return res.success === false;
} Try / catch
try {
const { clientSecret, redirectUrl } = await createCheckoutSession(req);
startEmbeddedCheckout(clientSecret, redirectUrl);
} catch (e) {
if (e instanceof StripeFunctionError) {
notifications.show({ message: e.message, color: "red" });
} else throw e;
} Prevention
- Ensure every failure branch in create-checkout-session returns { success: false, error }.
- Verify the Stripe secret key + price config the function reads.
- Always catch StripeFunctionError at the checkout call site and surface e.message.
When it happens
Trigger: create-checkout-session responds { success: false } (no error string). The right-hand operand of `res.error ?? fallback`, so it only fires when error is null/undefined/empty.
Common situations: Edge function hit an error branch that returns { success: false } without setting error; a Stripe API failure inside the function was swallowed; a refactored response shape dropped the error field.
Related errors
- create-checkout-session returned neither client_secret nor U
- 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/4a107cc48101bbca.
Report an issue: GitHub.