{"record":{"id":"80379d3ae63963f8","repo":"moeru-ai/airi","slug":"stripe-checkout-url-missing","errorCode":"STRIPE_CHECKOUT_URL_MISSING","errorMessage":"Stripe checkout did not return a URL","messagePattern":"Stripe checkout did not return a URL","errorType":"http","errorClass":"ApiError","httpStatus":503,"severity":"error","filePath":"server/apps/api/src/routes/stripe/operations/checkout.ts","lineNumber":99,"sourceCode":"\n    if (Object.keys(paymentMethodOptions).length > 0)\n      sessionParams.payment_method_options = paymentMethodOptions as Stripe.Checkout.SessionCreateParams['payment_method_options']\n\n    if (currency)\n      sessionParams.currency = currency\n\n    let session: Stripe.Checkout.Session\n    try {\n      session = await stripe.checkout.sessions.create(sessionParams)\n    }\n    catch (error) {\n      await payment.abandon(order.id)\n      throw error\n    }\n\n    if (!session.url) {\n      await payment.abandon(order.id)\n      throw createServiceUnavailableError('Stripe checkout did not return a URL', 'STRIPE_CHECKOUT_URL_MISSING')\n    }\n\n    await payment.bindProcessorOrder(order.id, {\n      processorOrderId: session.id,\n      amount: session.amount_total ?? undefined,\n      currency: session.currency ?? currency,\n    })\n\n    metrics?.stripeCheckoutCreated.add(1)\n    void productEventService?.track({\n      userId: user.id,\n      feature: 'billing',\n      action: 'checkout_started',\n      status: 'succeeded',\n      eventId: order.id,\n      source: 'stripe.checkout',\n      metadata: {\n        stripe_price_id: stripePriceId,","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/moeru-ai/airi/blob/438a067dde47aa0bdb46c2323d1fe293dc805218/server/apps/api/src/routes/stripe/operations/checkout.ts#L81-L117","documentation":"After creating a Stripe Checkout Session, the API expects session.url (the hosted payment page URL) to redirect the user. If Stripe returns a session without a URL, the pending order is abandoned and the API throws 503 STRIPE_CHECKOUT_URL_MISSING.","triggerScenarios":"stripe.checkout.sessions.create returning a session object with url === null/undefined, typically when the session was created in a mode/configuration that does not yield a hosted URL, or an unexpected Stripe API response.","commonSituations":"Stripe API version drift changing response shape; creating sessions with unusual parameters (e.g. custom payment method configurations); transient Stripe API incidents returning partial sessions.","solutions":["Retry the checkout; if transient, a fresh session should include the URL.","Check the Stripe API version pinned by the server SDK against the expected response shape (session.url).","Inspect the full session object in logs to see why URL is absent and adjust session creation parameters.","Check Stripe status/incidents if it started failing broadly."],"exampleFix":"// before\nconst session = await stripe.checkout.sessions.create(params)\nreturn session.url // may be null\n// after\nconst session = await stripe.checkout.sessions.create(params)\nif (!session.url) throw createServiceUnavailableError('Stripe checkout did not return a URL', 'STRIPE_CHECKOUT_URL_MISSING')\nreturn session.url","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const { url } = await checkout(body)\n} catch (e) {\n  if (e.code === 'STRIPE_CHECKOUT_URL_MISSING') {\n    // safe to retry: the pending order was abandoned server-side\n    await retryWithBackoff(() => checkout(body))\n  }\n}","preventionTips":["Pin and test against a specific Stripe API version so session.url is always present.","Monitor Stripe status pages and alert on checkout failure spikes.","Log the full session object on this error to speed diagnosis."],"tags":["stripe","checkout","unexpected-response","service-unavailable"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"438a067dde47aa0bdb46c2323d1fe293dc805218","analyzedAt":"2026-09-17T01:14:42.644Z","contentChangedAt":"2026-09-17T01:14:42.644Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}