{"record":{"id":"462d7565a966cbb0","repo":"TryGhost/Ghost","slug":"latest-stripe-checkout-session-does-not-include-a","errorCode":null,"errorMessage":"Latest Stripe checkout session does not include a success URL","messagePattern":"Latest Stripe checkout session does not include a success URL","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"e2e/helpers/playwright/flows/donations.ts","lineNumber":39,"sourceCode":"        await checkoutPage.fillEmail(opts.email);\n    }\n\n    const amount = await checkoutPage.getAmountInCents();\n    const email = await checkoutPage.getEmail();\n\n    await checkoutPage.submitPayment();\n    await stripe.completeLatestDonationCheckout({\n        amount,\n        donationMessage: opts.donationMessage,\n        email,\n        name: opts.name\n    });\n\n    const latestCheckoutSession = stripe.getCheckoutSessions().at(-1);\n    const successUrl = latestCheckoutSession?.response.success_url;\n\n    if (!successUrl) {\n        throw new Error('Latest Stripe checkout session does not include a success URL');\n    }\n\n    await page.goto(successUrl);\n}\n","sourceCodeStart":21,"sourceCodeEnd":44,"githubUrl":"https://github.com/TryGhost/Ghost/blob/47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe/e2e/helpers/playwright/flows/donations.ts#L21-L44","documentation":"Thrown in the `donateViaStripeCheckout` flow after `stripe.completeLatestDonationCheckout`. The flow reads `stripe.getCheckoutSessions().at(-1)?.response.success_url`; if no checkout session was recorded by the Stripe test service or its `response` lacks a `success_url`, the navigation target is undefined and the test aborts. It guards the subsequent `page.goto(successUrl)` from navigating to nothing.","triggerScenarios":"The donation checkout flow runs, but the Stripe fake/test server captured zero checkout sessions (webhook not delivered, `submitPayment` did not trigger checkout creation), or the recorded session object has no `success_url` on its `response` payload.","commonSituations":"Stripe test service is not intercepting checkout creation; the FakeStripeCheckoutPage submission silently failed before a session was created; a version change in the Stripe mock changed the session response shape; running with `stripeEnabled` configuration off so no session is ever created.","solutions":["Confirm the Stripe test service is connected and `stripe.getCheckoutSessions()` returns entries (log its length right after `completeLatestDonationCheckout`).","Verify `checkoutPage.submitPayment()` actually completed and the fake Stripe server recorded the session before reading it.","Ensure the test environment has Stripe enabled (the fixture forces per-test isolation for stripe tests).","If the session exists but lacks `success_url`, inspect the session payload shape returned by the Stripe mock and update the access path."],"exampleFix":"// before\nconst latestCheckoutSession = stripe.getCheckoutSessions().at(-1);\nconst successUrl = latestCheckoutSession?.response.success_url;\nif (!successUrl) {\n    throw new Error('Latest Stripe checkout session does not include a success URL');\n}\n\n// after — surface why it failed\nconst sessions = stripe.getCheckoutSessions();\nconst latest = sessions.at(-1);\nif (!latest) {\n    throw new Error(`No Stripe checkout sessions recorded (count=${sessions.length})`);\n}\nconst successUrl = latest.response?.success_url;\nif (!successUrl) {\n    throw new Error(`Checkout session ${latest.id} has no success_url: ${JSON.stringify(latest.response)}`);\n}","handlingStrategy":"validation","validationCode":"const sessions = stripe.getCheckoutSessions();\nif (sessions.length === 0) {\n    throw new Error('No Stripe checkout sessions recorded — checkout did not complete');\n}\nconst successUrl = sessions.at(-1)!.response.success_url;","typeGuard":"function hasSuccessUrl(s: unknown): s is {response: {success_url: string}} {\n    return typeof s === 'object' && s !== null\n        && typeof (s as any).response?.success_url === 'string';\n}","tryCatchPattern":null,"preventionTips":["Confirm the Stripe test service is intercepting checkout creation before the flow runs.","Ensure `stripeEnabled` is on for the test (the fixture forces per-test isolation for stripe tests).","Log `stripe.getCheckoutSessions().length` during checkout-flow debugging."],"tags":["stripe","e2e","checkout","donations"],"backgroundTag":null,"analyzedSha":"47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe","analyzedAt":"2026-08-13T01:25:26.651Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}