{"record":{"id":"2433f1cdded2d166","repo":"payloadcms/payload","slug":"variant-with-id-variant-id-does-not-have-a-pric","errorCode":null,"errorMessage":"Variant with ID ${variant.id} does not have a price in ${currency}.","messagePattern":"Variant with ID (.+?) does not have a price in (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/plugin-ecommerce/src/utilities/defaultProductsValidation.ts","lineNumber":20,"sourceCode":"\nimport { MissingPrice, OutOfStock } from './errorCodes.js'\n\nexport const defaultProductsValidation: ProductsValidation = ({\n  currenciesConfig,\n  currency,\n  product,\n  quantity = 1,\n  variant,\n}) => {\n  if (!currency) {\n    throw new Error('Currency must be provided for product validation.')\n  }\n\n  const priceField = `priceIn${currency.toUpperCase()}`\n\n  if (variant) {\n    if (!variant[priceField]) {\n      throw new Error(`Variant with ID ${variant.id} does not have a price in ${currency}.`)\n    }\n\n    if (variant.inventory === 0 || (variant.inventory && variant.inventory < quantity)) {\n      throw new Error(\n        `Variant with ID ${variant.id} is out of stock or does not have enough inventory.`,\n      )\n    }\n  } else if (product) {\n    // Validate the product's details only if the variant is not provided as it can have its own inventory and price\n    if (!product[priceField]) {\n      throw new Error(`Product does not have a price in.`, {\n        cause: { code: MissingPrice, codes: [product.id, currency] },\n      })\n    }\n\n    if (product.inventory === 0 || (product.inventory && product.inventory < quantity)) {\n      throw new Error(`Product is out of stock or does not have enough inventory.`, {\n        cause: { code: OutOfStock, codes: [product.id] },","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/payloadcms/payload/blob/00c58b35c0ed348ddc22daabf467b139727214fd/packages/plugin-ecommerce/src/utilities/defaultProductsValidation.ts#L2-L38","documentation":"Thrown by defaultProductsValidation when a variant is supplied but has no value for the dynamic price field priceIn<CURRENCY> (e.g. priceInUSD). The validator checks `!variant[priceField]`, so a variant defined without a price in the requested currency fails. This is a data-completeness error on the variant record.","triggerScenarios":"A cart item references a variant whose priceIn<CURRENCY> field is unset/zero/falsy for the currency the customer is checking out in. Triggered during cart validation or checkout when quantity is being confirmed against a variant.","commonSituations":"Multi-currency store where the variant has prices for some currencies but not the one selected; new variant created without filling all configured currency price fields; currency recently added to currenciesConfig but existing variants not backfilled; variant imported with partial price data.","solutions":["Backfill the missing price field on the variant for the requested currency.","Restrict checkout to currencies for which the variant has a price, or hide the variant for unsupported currencies.","Validate variant price completeness when creating/updating variants (admin hook) so gaps never reach checkout.","Confirm the currency string matches the suffix in the price field name (case-insensitive — the code uppercases it)."],"exampleFix":"// before: variant has priceInUSD but not priceInEUR\nconst variant = { id: 1, priceInUSD: 1000 } // EUR checkout fails\n// after: backfill or restrict currency\nconst variant = { id: 1, priceInUSD: 1000, priceInEUR: 920 }","handlingStrategy":"validation","validationCode":"function variantHasPriceInCurrency(variant: Record<string, unknown>, currency: string): boolean {\n  const field = `priceIn${currency.toUpperCase()}`\n  const v = variant[field]\n  return typeof v === 'number' ? v > 0 : Boolean(v)\n}\n\nif (!variantHasPriceInCurrency(variant, currency)) {\n  throw new Error(`Variant ${variant.id} has no price in ${currency}`)\n}","typeGuard":"export function variantHasPrice(variant: Record<string, unknown>, currency: string): boolean {\n  const v = variant[`priceIn${currency.toUpperCase()}`]\n  return typeof v === 'number' ? v > 0 : Boolean(v)\n}","tryCatchPattern":"try {\n  defaultProductsValidation({ currency, variant, quantity })\n} catch (err) {\n  if (err instanceof Error && /does not have a price in/.test(err.message)) {\n    // hide the variant for this currency, or prompt admin to backfill\n    return { ok: false, reason: 'variant-missing-price', variantId: variant.id, currency }\n  }\n  throw err\n}","preventionTips":["Backfill priceIn<CURRENCY> for all configured currencies when creating a variant.","Add an admin hook requiring all currency price fields on variant create/update.","Restrict selectable currencies to those the variant is priced in.","Confirm the currency string case matches the field suffix (the code uppercases it)."],"tags":["validation","variant","price","currency","ecommerce","data-integrity"],"backgroundTag":null,"analyzedSha":"00c58b35c0ed348ddc22daabf467b139727214fd","analyzedAt":"2026-08-12T20:45:03.758Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}