{"record":{"id":"c792661efc9f9017","repo":"medusajs/medusa","slug":"variants-variantnotfoundorpublished-join","errorCode":null,"errorMessage":"Variants ${variantNotFoundOrPublished.join(\n          \", \"\n        )} do not exist or belong to a product that is not published","messagePattern":"Variants (.+?) do not exist or belong to a product that is not published","errorType":"exception","errorClass":"MedusaError","httpStatus":400,"severity":"error","filePath":"packages/core/core-flows/src/cart/workflows/get-variants-and-items-with-prices.ts","lineNumber":164,"sourceCode":"        isCustomPrice: isCustomPrice,\n      }\n\n      if (variant && !isCustomPrice && calculatedPriceSet) {\n        input.unitPrice = calculatedPriceSet.calculated_amount\n        input.isTaxInclusive =\n          calculatedPriceSet.is_calculated_price_tax_inclusive\n      }\n\n      const preparedItem = prepareLineItemData(input)\n\n      return {\n        selector: { id: (item_ as CartLineItemDTO).id },\n        data: preparedItem as Partial<UpdateLineItemDTO>,\n      }\n    })\n\n    if (variantNotFoundOrPublished.length > 0) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        `Variants ${variantNotFoundOrPublished.join(\n          \", \"\n        )} do not exist or belong to a product that is not published`\n      )\n    }\n    if (priceNotFound.length > 0) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        `Variants with IDs ${priceNotFound.join(\", \")} do not have a price`\n      )\n    }\n\n    const result: GetVariantsAndItemsWithPricesWorkflowOutput = {\n      variants: variantsData,\n      lineItems: items,\n    }\n    return new StepResponse(result)","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/core/core-flows/src/cart/workflows/get-variants-and-items-with-prices.ts#L146-L182","documentation":"getVariantsAndItemsWithPricesWorkflow validates every requested variant id against fetched, published products. Ids that resolve to nothing — deleted/nonexistent variants or variants of unpublished products — are collected and reported in one aggregate invalid_data error.","triggerScenarios":"Calling addToCartWorkflow / updateCart with variant ids that don't exist, whose products have status != 'published', or that were soft-deleted; also stale ids cached in the client.","commonSituations":"Storefront caching product/variant data past unpublish or deletion; drafts mistakenly exposed to the storefront; re-using seed data ids after a DB reset; products unpublished during a sale window while carts remain active.","solutions":["Verify the variant exists and its product status is 'published' before adding it to a cart","Publish the product via Admin (POST /admin/products/:id/publish) if it should be sellable","Invalidate storefront caches when products/variants change","Handle 404s from catalog endpoints so stale ids never reach the cart"],"exampleFix":"// before\nawait addToCartWorkflow(container).run({ input: { cart_id, items: [{ variant_id, quantity: 1 }] } })\n\n// after\nconst { data } = await query.graph({ entity: 'variant', fields: ['id', 'product.status'], filters: { id: variant_id } })\nif (!data[0] || data[0].product.status !== 'published') throw new Error('Variant unavailable')\nawait addToCartWorkflow(container).run({ input: { cart_id, items: [{ variant_id, quantity: 1 }] } })","handlingStrategy":"validation","validationCode":"const { data } = await query.graph({ entity: 'variant', fields: ['id', 'product.status'], filters: { id: variantIds } })\nconst bad = variantIds.filter((id) => {\n  const v = data.find((x) => x.id === id)\n  return !v || v.product.status !== 'published'\n})\nif (bad.length) throw new Error(`Unavailable variants: ${bad.join(', ')}`)","typeGuard":"const isSellableVariant = (v?: VariantDTO): v is VariantDTO =>\n  !!v && v.product?.status === 'published'","tryCatchPattern":"try {\n  await addToCartWorkflow(container).run({ input })\n} catch (e) {\n  if (e instanceof MedusaError && /not published|do not exist/.test(e.message)) {\n    // remove unavailable ids from client state, show 'no longer available'\n  }\n}","preventionTips":["Invalidate product caches on publish/unpublish/delete events","Storefront adds should use ids from the live catalog response","Handle catalog 404s so stale ids never reach addToCart"],"tags":["cart","variant","product","publication"],"backgroundTag":"variant-not-found-or-unpublished","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}