{"record":{"id":"d814ad9af25f8090","repo":"medusajs/medusa","slug":"apply-to-quantity-is-a-required-field-for-promotio","errorCode":null,"errorMessage":"apply_to_quantity is a required field for Promotion type of ${PromotionType.BUYGET}","messagePattern":"apply_to_quantity is a required field for Promotion type of (.+?)","errorType":"validation","errorClass":"MedusaError","httpStatus":400,"severity":"error","filePath":"packages/modules/promotion/src/utils/validations/application-method.ts","lineNumber":61,"sourceCode":"  const applicationMethodType = data.type || applicationMethod?.type\n  const value = new BigNumber(data.value ?? applicationMethod.value ?? 0)\n  const maxQuantity = data.max_quantity || applicationMethod.max_quantity\n  const allocation = data.allocation || applicationMethod.allocation\n  const allTargetTypes: string[] = Object.values(ApplicationMethodTargetType)\n\n  if (\n    type === ApplicationMethodType.PERCENTAGE &&\n    (MathBN.lte(value, 0) || MathBN.gt(value, 100))\n  ) {\n    throw new MedusaError(\n      MedusaError.Types.INVALID_DATA,\n      `Application Method value should be a percentage number between 0 and 100`\n    )\n  }\n\n  if (promotion?.type === PromotionType.BUYGET) {\n    if (!isPresent(applyToQuantity)) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        `apply_to_quantity is a required field for Promotion type of ${PromotionType.BUYGET}`\n      )\n    }\n\n    if (!isPresent(buyRulesMinQuantity)) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        `buy_rules_min_quantity is a required field for Promotion type of ${PromotionType.BUYGET}`\n      )\n    }\n\n    if (!isPresent(maxQuantity)) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        `application_method.max_quantity is a required field for Promotion type of ${PromotionType.BUYGET}`\n      )\n    }","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/modules/promotion/src/utils/validations/application-method.ts#L43-L79","documentation":"For buy-get promotions, application_method.apply_to_quantity (how many items the customer gets discounted) must be present. The BUYGET branch of validateApplicationMethodAttributes throws INVALID_DATA when it is missing.","triggerScenarios":"Creating a promotion with type 'buyget' whose application_method omits apply_to_quantity, or an update that clears it.","commonSituations":"Copy-pasting a standard promotion payload for a buy-get promo and forgetting the buy-get-only fields, admin form not rendering buy-get fields conditionally, partial updates that unset the field with null.","solutions":["Add apply_to_quantity to the application_method payload (e.g., 1 for buy-1-get-1)","Ensure the admin/custom form collects apply_to_quantity when promotion type is buyget","Never send null for the field on updates; send the full buy-get field set"],"exampleFix":"// before\nawait promotionModule.createPromotions({ code: \"B2G1\", type: \"buyget\", application_method: { type: \"percentage\", value: 100, target_type: \"items\", buy_rules_min_quantity: 2 } })\n\n// after\nawait promotionModule.createPromotions({ code: \"B2G1\", type: \"buyget\", application_method: { type: \"percentage\", value: 100, target_type: \"items\", apply_to_quantity: 1, buy_rules_min_quantity: 2, max_quantity: 1 } })","handlingStrategy":"validation","validationCode":"if (promo.type === \"buyget\") {\n  const required = [\"apply_to_quantity\", \"buy_rules_min_quantity\", \"max_quantity\"]\n  const missing = required.filter((k) => !isPresent(promo.application_method?.[k]))\n  if (missing.length) throw new Error(`missing: ${missing.join(\", \")}`)\n}","typeGuard":"const isCompleteBuyGetMethod = (am: Record<string, unknown> | undefined): boolean => !!am && [\"apply_to_quantity\", \"buy_rules_min_quantity\", \"max_quantity\"].every((k) => am[k] != null)","tryCatchPattern":"try { await createPromotions(...) } catch (e) { if (e.type === MedusaError.Types.INVALID_DATA && /apply_to_quantity is a required field/.test(e.message)) { /* add the field and resubmit */ } throw e }","preventionTips":["Use one shared buy-get payload template with all required fields","Show all buy-get fields when type is buyget in the UI","Validate the full field set before submit"],"tags":["promotion","buy-get","validation","required-field","medusa"],"backgroundTag":"missing-required-field","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}