moeru-ai/airi · error · ApiError

STRIPE_CHECKOUT_URL_MISSING

STRIPE_CHECKOUT_URL_MISSING

Error message

Stripe checkout did not return a URL

What it means

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.

Solutions

  1. Retry the checkout; if transient, a fresh session should include the URL.
  2. Check the Stripe API version pinned by the server SDK against the expected response shape (session.url).
  3. Inspect the full session object in logs to see why URL is absent and adjust session creation parameters.
  4. Check Stripe status/incidents if it started failing broadly.

Example fix

// before
const session = await stripe.checkout.sessions.create(params)
return session.url // may be null
// after
const session = await stripe.checkout.sessions.create(params)
if (!session.url) throw createServiceUnavailableError('Stripe checkout did not return a URL', 'STRIPE_CHECKOUT_URL_MISSING')
return session.url
Defensive patterns

Strategy: retry

Try / catch

try {
  const { url } = await checkout(body)
} catch (e) {
  if (e.code === 'STRIPE_CHECKOUT_URL_MISSING') {
    // safe to retry: the pending order was abandoned server-side
    await retryWithBackoff(() => checkout(body))
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of moeru-ai/airi@438a067dde (2026-09-17). Data as JSON: /api/errors/80379d3ae63963f8. Report an issue: GitHub.

Appendix: source

Thrown at server/apps/api/src/routes/stripe/operations/checkout.ts:99

    if (Object.keys(paymentMethodOptions).length > 0)
      sessionParams.payment_method_options = paymentMethodOptions as Stripe.Checkout.SessionCreateParams['payment_method_options']

    if (currency)
      sessionParams.currency = currency

    let session: Stripe.Checkout.Session
    try {
      session = await stripe.checkout.sessions.create(sessionParams)
    }
    catch (error) {
      await payment.abandon(order.id)
      throw error
    }

    if (!session.url) {
      await payment.abandon(order.id)
      throw createServiceUnavailableError('Stripe checkout did not return a URL', 'STRIPE_CHECKOUT_URL_MISSING')
    }

    await payment.bindProcessorOrder(order.id, {
      processorOrderId: session.id,
      amount: session.amount_total ?? undefined,
      currency: session.currency ?? currency,
    })

    metrics?.stripeCheckoutCreated.add(1)
    void productEventService?.track({
      userId: user.id,
      feature: 'billing',
      action: 'checkout_started',
      status: 'succeeded',
      eventId: order.id,
      source: 'stripe.checkout',
      metadata: {
        stripe_price_id: stripePriceId,

View on GitHub (pinned to 438a067dde)