TryGhost/Ghost · error · Error
result.error.message
Error message
result.error.message
What it means
Thrown inside editBilling() after the backend returned a valid update session but Stripe.js redirectToCheckout() failed. Same Stripe-redirect failure class as errors 81/83, scoped to the card-update (billing edit) flow. The session was created; the browser-side handoff to Stripe's hosted checkout broke.
Source
Thrown at apps/portal/src/utils/api.js:768
body: JSON.stringify({
identity: identity,
subscription_id: subscriptionId,
successUrl,
cancelUrl
})
}).then(function (res) {
if (!res.ok) {
throw new Error('Unable to create stripe checkout session');
}
return res.json();
}).then(function (result) {
const stripe = window.Stripe(result.publicKey);
return stripe.redirectToCheckout({
sessionId: result.sessionId
});
}).then(function (result) {
if (result.error) {
throw new Error(result.error.message);
}
}).catch(function (err) {
throw err;
});
},
async manageBilling({returnUrl, subscriptionId} = {}) {
const identity = await api.member.identity();
const url = endpointFor({type: 'members', resource: 'create-stripe-billing-portal-session'});
if (!returnUrl) {
const returnUrlObj = new URL(siteUrl);
returnUrlObj.searchParams.set('stripe', 'billing-portal-closed');
returnUrl = returnUrlObj.href;
}
return makeRequest({
url,
method: 'POST',View on GitHub (pinned to 47d8b0e2ad)
Solutions
- Close and reopen the edit-billing flow to mint a fresh session.
- Verify Stripe publishable key parity in Ghost Admin settings.
- Check browser console for the Stripe.js error code/type.
- Consult status.stripe.com for a Checkout incident.
Defensive patterns
Strategy: try-catch
Validate before calling
function stripeReady() {
return typeof window.Stripe === 'function';
} Type guard
function isStripeRedirectError(result) {
return result && typeof result.error === 'object' && typeof result.error.message === 'string';
} Try / catch
try {
await api.member.editBilling({subscriptionId});
} catch (err) {
if (/session|stripe/i.test(err.message)) {
// re-enter edit billing to mint a fresh session
}
showToast(err.message);
} Prevention
- Reopen the edit-billing flow to get a fresh Stripe session.
- Keep Stripe keys consistent; block-check js.stripe.com reachability.
- Treat Stripe redirect errors as retryable.
When it happens
Trigger: stripe.redirectToCheckout({sessionId}) resolves with {error} for the billing-update session — expired sessionId, publishable key mismatch with the session's account, Stripe.js blocked, or the session already consumed.
Common situations: Member opened the edit-billing flow, left it idle past the session expiry, then clicked through; Stripe keys changed in Ghost Admin between session creation and redirect; Stripe.js blocked by CSP/ad-blocker; Stripe partial outage on Checkout.
Related errors
- redirectResult.error.message
- Unable to create stripe checkout session
- Could not create Stripe checkout session
- redirectResult.error.message
- result.error.message
AI-assisted analysis of TryGhost/Ghost@47d8b0e2ad (2026-08-13).
Data as JSON: /api/errors/1495f861b05967a6.
Report an issue: GitHub.