medusajs/medusa · error · MedusaError

invalid_data

invalid_data

Error message

Variant does not have a product

What it means

prepareLineItemData requires that, when a variant is supplied, it carries its parent product (used for title/thumbnail/metadata on the line item). If variant is present but variant.product is undefined, the utility throws because it cannot construct a valid line item.

Source

Thrown at packages/core/core-flows/src/cart/utils/prepare-line-item-data.ts:96

  cartId?: string
  unitPrice?: BigNumberInput
  isTaxInclusive: boolean
}

export function prepareLineItemData(data: PrepareLineItemDataInput) {
  const {
    item,
    variant,
    cartId,
    taxLines,
    adjustments,
    isCustomPrice,
    unitPrice,
    isTaxInclusive,
  } = data

  if (variant && !variant.product) {
    throw new MedusaError(
      MedusaError.Types.INVALID_DATA,
      "Variant does not have a product"
    )
  }

  if (item && MathBN.lte(item.quantity, 0)) {
    throw new MedusaError(
      MedusaError.Types.INVALID_DATA,
      "Item quantity must be greater than 0"
    )
  }

  let compareAtUnitPrice = item?.compare_at_unit_price

  const isSalePrice =
    variant?.calculated_price?.calculated_price?.price_list_type ===
    PriceListType.SALE

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Ensure the variant passed in includes the product relation (include 'product.*' when querying variants)
  2. If building input manually, fetch the product and attach it before calling the utility
  3. Repair broken variant-product links in the Product module if the relation is genuinely missing

Example fix

// before
const variants = await query.graph({ entity: 'variant', filters: { id: variantIds }, fields: ['*'] })
const item = prepareLineItemData({ variant: variants[0], quantity: 1 })

// after
const variants = await query.graph({ entity: 'variant', filters: { id: variantIds }, fields: ['*', 'product.*'] })
const item = prepareLineItemData({ variant: variants[0], quantity: 1 })
Defensive patterns

Strategy: validation

Validate before calling

if (input.variant && !input.variant.product) {
  throw new Error('Load the variant with its product relation before preparing line item data')
}

Type guard

const variantWithProduct = (
  v: VariantDTO
): v is VariantDTO & { product: ProductDTO } => Boolean(v.product)

Prevention

When it happens

Trigger: Calling prepareLineItemData (directly or via addToCartWorkflow / updateLineItemsWorkflow) with a variant object that was fetched without the product relation, or a variant whose link to its product is broken.

Common situations: Custom code or plugins loading variants with remoteQuery/graph without selecting product; stale or corrupted variant-product links after data imports; passing a partially-built variant DTO instead of a full variant.

Related errors


AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27). Data as JSON: /api/errors/9c94f749e1b9d191. Report an issue: GitHub.