moeru-ai/airi · error · ApiError

STRIPE_NOT_CONFIGURED

STRIPE_NOT_CONFIGURED

Error message

Stripe is not configured

What it means

createCheckoutOperation requires three configured pieces: a Stripe client, a price catalog, and the STRIPE_FLUX_PRODUCT_ID config value. If any is missing (Stripe integration not initialized or product ID not set), checkout cannot proceed and the API returns 503 with STRIPE_NOT_CONFIGURED.

Solutions

  1. Set STRIPE_FLUX_PRODUCT_ID via configKV (or your config mechanism) to a valid Stripe product ID.
  2. Ensure the Stripe client is initialized (verify STRIPE_SECRET_KEY is present and valid at server startup).
  3. Verify the price catalog loads successfully (check its initialization logs/dependencies).
  4. Restart the API after adding the configuration so dependencies re-initialize.

Example fix

// before (config missing)
// configKV has no STRIPE_FLUX_PRODUCT_ID
// after
await configKV.set('STRIPE_FLUX_PRODUCT_ID', 'prod_xxx')
Defensive patterns

Strategy: try-catch

Validate before calling

const fluxProductId = await configKV.getOptional('STRIPE_FLUX_PRODUCT_ID')
if (!stripe || !priceCatalog || !fluxProductId) {
  // disable checkout UI / show 'billing unavailable'
}

Try / catch

try {
  const { url } = await api.post('/checkout', body)
} catch (e) {
  if (e.code === 'STRIPE_NOT_CONFIGURED') {
    // show 'payments are not available yet' message, do not retry
  }
}

Prevention

When it happens

Trigger: POSTing to the checkout route while: stripe client is null (STRIPE_SECRET_KEY missing/invalid at init), priceCatalog is null, or configKV has no 'STRIPE_FLUX_PRODUCT_ID' entry.

Common situations: Deploying without setting STRIPE_SECRET_KEY or STRIPE_FLUX_PRODUCT_ID in the environment/config KV; running the API locally against a docker-compose stack where Stripe config was never seeded; key rotation left the client uninitialized.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

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

import { CheckoutBodySchema } from '../schema'

export function createCheckoutOperation(
  payment: PaymentService,
  stripe: Stripe | null,
  priceCatalog: StripePriceCatalog | null,
  configKV: ConfigKVService,
  env: Env,
  metrics: RevenueMetrics | null,
  productEventService: ProductEventService | null,
) {
  return async (
    user: { id: string, email: string },
    body: unknown,
    request: Request,
  ): Promise<{ url: string }> => {
    const fluxProductId = await configKV.getOptional('STRIPE_FLUX_PRODUCT_ID')
    if (!stripe || !priceCatalog || !fluxProductId)
      throw createServiceUnavailableError('Stripe is not configured', 'STRIPE_NOT_CONFIGURED')

    const parsed = safeParse(CheckoutBodySchema, body)
    if (!parsed.success)
      throw createBadRequestError('Invalid checkout request', 'INVALID_REQUEST', parsed.issues)

    const { stripePriceId, currency } = parsed.output
    const price = await priceCatalog.findActivePrice(fluxProductId, stripePriceId)
    if (!price)
      throw createBadRequestError('Invalid price', 'INVALID_PACKAGE', { stripePriceId })

    const fluxAmount = Number(price.metadata.fluxAmount)
    if (!Number.isFinite(fluxAmount) || fluxAmount <= 0)
      throw createBadRequestError('Price is missing fluxAmount metadata', 'INVALID_PACKAGE', { stripePriceId })

    const redirectBase = resolveCheckoutRedirectBase(request, env.ADDITIONAL_TRUSTED_ORIGINS, env.WEB_APP_URL)
    const openpanelIdentity = readOpenpanelIdentityHeaders(request)

    const order = await payment.openPending({

View on GitHub (pinned to 438a067dde)