payloadcms/payload · error · Error
Currency must be provided for product validation.
Error message
Currency must be provided for product validation.
What it means
Thrown by defaultProductsValidation when the currency argument is falsy. The validator dynamically reads a per-currency price field (priceIn<CURRENCY>) on the product or variant, so without a currency it cannot decide which price to check. This guard runs before any price lookup and refuses to validate against an undefined currency.
Source
Thrown at packages/plugin-ecommerce/src/utilities/defaultProductsValidation.ts:13
import type { ProductsValidation } from '../types/index.js'
import { MissingPrice, OutOfStock } from './errorCodes.js'
export const defaultProductsValidation: ProductsValidation = ({
currenciesConfig,
currency,
product,
quantity = 1,
variant,
}) => {
if (!currency) {
throw new Error('Currency must be provided for product validation.')
}
const priceField = `priceIn${currency.toUpperCase()}`
if (variant) {
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.`, {View on GitHub (pinned to 00c58b35c0)
Solutions
- Pass the selected currency (e.g. 'usd') into every defaultProductsValidation call.
- Default currency from the plugin/store config if the caller omits it, then pass it through.
- Resolve currency once at the start of the checkout flow and thread it through every validation step.
- Add a runtime assertion on currency at the checkout entry point to fail fast with a clearer message.
Example fix
// before
defaultProductsValidation({ product, quantity })
// after
defaultProductsValidation({ currency: selectedCurrency, product, quantity }) Defensive patterns
Strategy: validation
Validate before calling
function resolveCurrencyForValidation(value: unknown, fallback?: string): string {
if (typeof value === 'string' && value.length > 0) return value
if (fallback) return fallback
throw new Error('Currency must be provided for product validation')
}
// resolve once, thread through validation
const currency = resolveCurrencyForValidation(input.currency, storeDefaultCurrency)
defaultProductsValidation({ currency, product, quantity }) Type guard
export function isNonEmptyCurrency(value: unknown): value is string {
return typeof value === 'string' && value.length > 0
} Try / catch
try {
defaultProductsValidation({ currency, product, quantity })
} catch (err) {
if (err instanceof Error && /Currency must be provided/.test(err.message)) {
// resolve currency from session/config and retry
return defaultProductsValidation({ currency: storeDefaultCurrency, product, quantity })
}
throw err
} Prevention
- Resolve currency once at checkout entry and pass it to every validation call.
- Default to the store's base currency when the customer hasn't selected one.
- Add a runtime assertion on currency at the checkout boundary to fail fast.
- Type the validation function so currency is required, preventing accidental omission.
When it happens
Trigger: defaultProductsValidation is called (directly or via the cart/checkout pipeline) with currency undefined/null/empty. The function signature requires currency; omitting it triggers the guard.
Common situations: Cart pipeline invoked before currency selection; multi-currency store where the selected currency isn't passed into the validation step; a custom validation wrapper that drops currency; SSR with no currency in session; default currency not set on the plugin config.
Related errors
- Currency is required.
- MissingPrice
- PaymentIntent ID is required
- A valid customer email is required to make a purchase.
- Variant with ID ${variant.id} does not have a price in ${cur
AI-assisted analysis of payloadcms/payload@00c58b35c0 (2026-08-12).
Data as JSON: /api/errors/e762417ab2469091.
Report an issue: GitHub.