payloadcms/payload · warning · Error

OutOfStock

OutOfStock

Error message

Product is out of stock or does not have enough inventory.

What it means

Thrown by defaultProductsValidation when no variant is supplied and the product's inventory is 0 or less than the requested quantity. The check `product.inventory === 0 || (product.inventory && product.inventory < quantity)` covers both fully out-of-stock and insufficient stock for the product branch. The error carries an ErrorOptions cause with code 'OutOfStock' and codes [product.id] for programmatic handling.

Source

Thrown at packages/plugin-ecommerce/src/utilities/defaultProductsValidation.ts:37

    if (!variant[priceField]) {
      throw new Error(`Variant with ID ${variant.id} does not have a price in ${currency}.`)
    }

    if (variant.inventory === 0 || (variant.inventory && variant.inventory < quantity)) {
      throw new Error(
        `Variant with ID ${variant.id} is out of stock or does not have enough inventory.`,
      )
    }
  } else if (product) {
    // Validate the product's details only if the variant is not provided as it can have its own inventory and price
    if (!product[priceField]) {
      throw new Error(`Product does not have a price in.`, {
        cause: { code: MissingPrice, codes: [product.id, currency] },
      })
    }

    if (product.inventory === 0 || (product.inventory && product.inventory < quantity)) {
      throw new Error(`Product is out of stock or does not have enough inventory.`, {
        cause: { code: OutOfStock, codes: [product.id] },
      })
    }
  }
}

View on GitHub (pinned to 00c58b35c0)

Solutions

  1. Re-fetch product inventory at checkout and reject or clamp the quantity.
  2. Decrement inventory atomically on order completion and reconcile with the source system.
  3. Cap the customer-selectable quantity to current stock on the product page.
  4. Inspect error.cause.code === 'OutOfStock' to show a precise 'back in stock soon' message and capture demand (email signup).

Example fix

// before: stale stock at checkout
const product = await findByID(id) // inventory 0
// after: re-read and clamp at confirm
const product = await findByID(id)
if (product.inventory < qty) qty = product.inventory
if (qty === 0) throw new Error('Out of stock')
Defensive patterns

Strategy: try-catch

Validate before calling

function productHasStock(product: { inventory?: number }, quantity: number): boolean {
  if (product.inventory === undefined) return true // untracked inventory
  return product.inventory === 0 ? false : product.inventory >= quantity
}

if (!productHasStock(product, quantity)) {
  const e = new Error(`Product ${product.id} is out of stock`)
  ;(e as any).cause = { code: 'OutOfStock', codes: [product.id] }
  throw e
}

Type guard

export function productHasEnoughStock(product: { inventory?: number }, quantity: number): boolean {
  return typeof product.inventory !== 'number' || product.inventory >= quantity
}

Try / catch

try {
  defaultProductsValidation({ currency, product, quantity })
} catch (err) {
  const cause = (err as Error & { cause?: { code?: string } }).cause
  if (cause?.code === 'OutOfStock') {
    // clamp quantity to available stock and retry, or surface a back-in-stock prompt
    const available = product.inventory ?? 0
    if (available > 0) return defaultProductsValidation({ currency, product, quantity: available })
    return { ok: false, reason: 'out-of-stock', productId: product.id }
  }
  throw err
}

Prevention

When it happens

Trigger: Cart/checkout validation where a product (no variant) has inventory 0 or below the requested quantity. Triggered in the product branch after the price check passed.

Common situations: Sales depleting stock between add-to-cart and checkout; stale inventory cache; admin marking a product out of stock (inventory 0) without unpublishing; bulk orders exceeding available quantity; inventory sync delay from an external system.

Related errors


AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12). Data as JSON: /api/errors/ba7b9e1d67d5ce45. Report an issue: GitHub.