{"record":{"id":"9c94f749e1b9d191","repo":"medusajs/medusa","slug":"invalid-data-9c94f7","errorCode":"invalid_data","errorMessage":"Variant does not have a product","messagePattern":"Variant does not have a product","errorType":"validation","errorClass":"MedusaError","httpStatus":400,"severity":"error","filePath":"packages/core/core-flows/src/cart/utils/prepare-line-item-data.ts","lineNumber":96,"sourceCode":"  cartId?: string\n  unitPrice?: BigNumberInput\n  isTaxInclusive: boolean\n}\n\nexport function prepareLineItemData(data: PrepareLineItemDataInput) {\n  const {\n    item,\n    variant,\n    cartId,\n    taxLines,\n    adjustments,\n    isCustomPrice,\n    unitPrice,\n    isTaxInclusive,\n  } = data\n\n  if (variant && !variant.product) {\n    throw new MedusaError(\n      MedusaError.Types.INVALID_DATA,\n      \"Variant does not have a product\"\n    )\n  }\n\n  if (item && MathBN.lte(item.quantity, 0)) {\n    throw new MedusaError(\n      MedusaError.Types.INVALID_DATA,\n      \"Item quantity must be greater than 0\"\n    )\n  }\n\n  let compareAtUnitPrice = item?.compare_at_unit_price\n\n  const isSalePrice =\n    variant?.calculated_price?.calculated_price?.price_list_type ===\n    PriceListType.SALE\n","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/core/core-flows/src/cart/utils/prepare-line-item-data.ts#L78-L114","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the variant passed in includes the product relation (include 'product.*' when querying variants)","If building input manually, fetch the product and attach it before calling the utility","Repair broken variant-product links in the Product module if the relation is genuinely missing"],"exampleFix":"// before\nconst variants = await query.graph({ entity: 'variant', filters: { id: variantIds }, fields: ['*'] })\nconst item = prepareLineItemData({ variant: variants[0], quantity: 1 })\n\n// after\nconst variants = await query.graph({ entity: 'variant', filters: { id: variantIds }, fields: ['*', 'product.*'] })\nconst item = prepareLineItemData({ variant: variants[0], quantity: 1 })","handlingStrategy":"validation","validationCode":"if (input.variant && !input.variant.product) {\n  throw new Error('Load the variant with its product relation before preparing line item data')\n}","typeGuard":"const variantWithProduct = (\n  v: VariantDTO\n): v is VariantDTO & { product: ProductDTO } => Boolean(v.product)","tryCatchPattern":null,"preventionTips":["Always select 'product.*' when fetching variants used for cart operations","Type your inputs as Variant & { product: Product } so the compiler enforces the relation"],"tags":["cart","line-item","variant","relation","typescript"],"backgroundTag":"missing-relation-not-loaded","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}