{"record":{"id":"7d24913f962aa6d9","repo":"payloadcms/payload","slug":"cart-is-empty-or-not-provided","errorCode":null,"errorMessage":"Cart is empty or not provided.","messagePattern":"Cart is empty or not provided\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/plugin-ecommerce/src/payments/adapters/stripe/initiatePayment.ts","lineNumber":34,"sourceCode":"    const { apiVersion, appInfo, secretKey } = props || {}\n\n    const customerEmail = data.customerEmail\n    const currency = data.currency\n    const cart = data.cart\n    const amount = cart.subtotal\n    const billingAddressFromData = data.billingAddress\n    const shippingAddressFromData = data.shippingAddress\n\n    if (!secretKey) {\n      throw new Error('Stripe secret key is required.')\n    }\n\n    if (!currency) {\n      throw new Error('Currency is required.')\n    }\n\n    if (!cart || !cart.items || cart.items.length === 0) {\n      throw new Error('Cart is empty or not provided.')\n    }\n\n    if (!customerEmail || typeof customerEmail !== 'string') {\n      throw new Error('A valid customer email is required to make a purchase.')\n    }\n\n    if (!amount || typeof amount !== 'number' || amount <= 0) {\n      throw new Error('A valid amount is required to initiate a payment.')\n    }\n\n    const stripe = new Stripe(secretKey, {\n      // API version can only be the latest, stripe recommends ts ignoring it\n      // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n      // @ts-ignore - ignoring since possible versions are not type safe, only the latest version is recognised\n      apiVersion: apiVersion || '2025-06-30.preview',\n      appInfo: appInfo || {\n        name: 'Stripe Payload Plugin',\n        url: 'https://payloadcms.com',","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/plugin-ecommerce/src/payments/adapters/stripe/initiatePayment.ts#L16-L52","documentation":"Thrown by Stripe initiatePayment when data.cart is missing, has no items array, or items is empty. The adapter needs cart.items to compute the flattened snapshot stored in PaymentIntent metadata and to record the transaction. An empty cart cannot produce a valid payment, so initiation is refused before any Stripe call.","triggerScenarios":"initiatePayment called with no cart, a cart object lacking items, or items: []. The check is `!cart || !cart.items || cart.items.length === 0`.","commonSituations":"Checkout button enabled on an empty cart; cart state lost between page and checkout; race where the cart is cleared before payment starts; cart stored under a different shape (e.g. data.items instead of data.cart.items); SSR-rendered page with no hydrated cart.","solutions":["Disable the checkout/pay button until the cart has at least one item.","Fetch the cart server-side and ensure items is a non-empty array before calling initiatePayment.","Validate cart structure client-side: assert Array.isArray(cart.items) && cart.items.length > 0.","If using a cart slug with a different field name, map it to items before initiate."],"exampleFix":"// before\nawait payments.initiatePayment({ data: { currency, customerEmail } }) // no cart\n// after\nif (!cart?.items?.length) throw new Error('Cart is empty')\nawait payments.initiatePayment({ data: { cart, currency, customerEmail } })","handlingStrategy":"type-guard","validationCode":"export function isNonEmptyCart(cart: unknown): cart is { id: string; items: unknown[]; subtotal: number } {\n  return (\n    typeof cart === 'object' && cart !== null &&\n    Array.isArray((cart as { items?: unknown }).items) &&\n    ((cart as { items: unknown[] }).items.length > 0)\n  )\n}\n\nif (!isNonEmptyCart(data.cart)) throw new Error('Cart must contain at least one item')\nawait payments.initiatePayment({ data })","typeGuard":"export function isNonEmptyCart(cart: unknown): cart is { items: unknown[] } {\n  return typeof cart === 'object' && cart !== null && Array.isArray((cart as { items?: unknown }).items) && (cart as { items: unknown[] }).items.length > 0\n}","tryCatchPattern":"try {\n  await payments.initiatePayment({ data })\n} catch (err) {\n  if (err instanceof Error && /Cart is empty/.test(err.message)) {\n    // prompt the customer to add items\n    return { ok: false, reason: 'empty-cart', redirect: '/cart' }\n  }\n  throw err\n}","preventionTips":["Disable checkout until the cart has at least one item.","Validate cart shape (items is a non-empty array) before calling initiatePayment.","Re-fetch the cart server-side at checkout to avoid stale client state.","Map your cart field names to { items: [...] } before initiate."],"tags":["stripe","cart","validation","ecommerce","checkout"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}