{"record":{"id":"7d753f1bfa0bbe6f","repo":"medusajs/medusa","slug":"cannot-associate-duplicate-inventory-items-to-vari","errorCode":null,"errorMessage":"Cannot associate duplicate inventory items to variant(s) ${erroredVariantIds.join(\"\\n\")}","messagePattern":"Cannot associate duplicate inventory items to variant\\(s\\) (.+?)","errorType":"validation","errorClass":"MedusaError","httpStatus":400,"severity":"error","filePath":"packages/core/core-flows/src/product/workflows/create-product-variants.ts","lineNumber":103,"sourceCode":"  }[]\n) => {\n  const erroredVariantIds: string[] = []\n\n  for (const variantData of variantsData) {\n    const inventoryItemIds = variantData.inventory_items.map(\n      (item) => item.inventory_item_id\n    )\n    const duplicatedInventoryItemIds = inventoryItemIds.filter(\n      (id, index) => inventoryItemIds.indexOf(id) !== index\n    )\n\n    if (duplicatedInventoryItemIds.length) {\n      erroredVariantIds.push(variantData.variantId)\n    }\n  }\n\n  if (erroredVariantIds.length) {\n    throw new MedusaError(\n      MedusaError.Types.INVALID_DATA,\n      `Cannot associate duplicate inventory items to variant(s) ${erroredVariantIds.join(\n        \"\\n\"\n      )}`\n    )\n  }\n}\n\nconst buildLinksToCreate = (data: {\n  createdVariants: ProductTypes.ProductVariantDTO[]\n  inventoryIndexMap: Record<number, InventoryTypes.InventoryItemDTO>\n  input: CreateProductVariantsWorkflowInput\n}) => {\n  let index = 0\n  const linksToCreate: LinkDefinition[] = []\n\n  validateVariantsDuplicateInventoryItemIds(\n    (data.createdVariants ?? []).map((variant, index) => {","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/core/core-flows/src/product/workflows/create-product-variants.ts#L85-L121","documentation":"Thrown by validateVariantsDuplicateInventoryItemIds when creating product variants whose inventory item links would assign the same inventory item to multiple variants (or the same item twice within one variant). Medusa prevents this because inventory levels are tracked per inventory item, and duplicating associations would corrupt stock accounting. It is an INVALID_DATA error raised during workflow validation before any data is written.","triggerScenarios":"Calling createProductVariantsWorkflow (or the admin POST /admin/products/:id/variants endpoint) with variant input where inventory_items arrays reference the same inventory_item_id across multiple variants, or the same id repeated within one variant's inventory_items list.","commonSituations":"Copying variant payload from an existing variant and forgetting to regenerate inventory items; mapping variants to a shared inventory pool incorrectly; migration scripts that assign one inventory item to every variant of a product.","solutions":["Inspect the workflow input and deduplicate: ensure each inventory_item_id appears in only one variant's inventory_items and only once per variant","If variants should share stock, keep a single variant or create separate inventory items per variant and adjust stock afterwards","Re-run the workflow after fixing the input payloads"],"exampleFix":"// before\nconst variants = [\n  { title: 'S', inventory_items: [{ inventory_item_id: 'iitem_1', required_quantity: 1 }] },\n  { title: 'M', inventory_items: [{ inventory_item_id: 'iitem_1', required_quantity: 1 }] }, // duplicate!\n]\n\n// after\nconst variants = [\n  { title: 'S', inventory_items: [{ inventory_item_id: 'iitem_1', required_quantity: 1 }] },\n  { title: 'M', inventory_items: [{ inventory_item_id: 'iitem_2', required_quantity: 1 }] },\n]","handlingStrategy":"validation","validationCode":"const seen = new Set<string>()\nfor (const v of variants) {\n  for (const ii of v.inventory_items ?? []) {\n    if (seen.has(ii.inventory_item_id)) throw new Error(`duplicate inventory item ${ii.inventory_item_id}`)\n    seen.add(ii.inventory_item_id)\n  }\n}","typeGuard":"const hasUniqueInventoryItems = (variants: CreateProductVariantInput[]): boolean => {\n  const seen = new Set<string>()\n  return variants.every((v) => (v.inventory_items ?? []).every((ii) => !seen.has(ii.inventory_item_id) && seen.add(ii.inventory_item_id)))\n}","tryCatchPattern":"try { await createProductVariantsWorkflow(scope).run({ input }) } catch (e) { if (e instanceof MedusaError && e.type === MedusaError.Types.INVALID_DATA && /duplicate inventory items/.test(e.message)) { /* dedupe input and retry */ } else throw e }","preventionTips":["Generate a fresh inventory item per variant instead of reusing ids","Never copy inventory_items arrays when cloning variant payloads","Run a dedupe check on inventory_item_id across the whole batch before invoking the workflow"],"tags":["product-variants","inventory","validation","core-flows"],"backgroundTag":"duplicate-entity-association","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}