{"record":{"id":"8401c63d40cd58c9","repo":"medusajs/medusa","slug":"application-method-apply-to-quantity-is-a-required","errorCode":null,"errorMessage":"application_method.apply_to_quantity is a required field for Promotion type of ${PromotionType.BUYGET}","messagePattern":"application_method\\.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":82,"sourceCode":"      )\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    }\n\n    if (!isPresent(applyToQuantity)) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        `application_method.apply_to_quantity is a required field for Promotion type of ${PromotionType.BUYGET}`\n      )\n    }\n\n    if (MathBN.lt(maxQuantity!, applyToQuantity!)) {\n      throw new MedusaError(\n        MedusaError.Types.INVALID_DATA,\n        `max_quantity (${maxQuantity}) must be greater than or equal to apply_to_quantity (${applyToQuantity}) for BUYGET promotions.`\n      )\n    }\n  }\n\n  if (\n    allocation === ApplicationMethodAllocation.ACROSS &&\n    isPresent(maxQuantity)\n  ) {\n    throw new MedusaError(","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/modules/promotion/src/utils/validations/application-method.ts#L64-L100","documentation":"For buy-get promotions, application_method.apply_to_quantity is required — this is the later redundant guard reached when earlier presence checks passed via different code paths (e.g., attribute spread/merge on update). It throws INVALID_DATA when the effective applyToQuantity is absent.","triggerScenarios":"Updating a buyget promotion with a partial application_method payload that carries max_quantity and buy_rules_min_quantity but drops apply_to_quantity (merged object ends up without it), or create payloads where the field is present but undefined.","commonSituations":"Patch-style updates that rebuild the application method object and lose fields, ORM hydration returning null, double-submit with partially validated data.","solutions":["Always send the complete buy-get application method on update, including apply_to_quantity","After building the payload, assert all three buy-get fields are defined before calling the module","Refetch the promotion and merge with existing application_method values instead of replacing"],"exampleFix":"// before\nawait promotionModule.updatePromotions({ id, application_method: { max_quantity: 2 } })\n\n// after\nconst existing = await promotionModule.retrievePromotion(id, { relations: [\"application_method\"] })\nawait promotionModule.updatePromotions({\n  id,\n  application_method: {\n    ...existing.application_method,\n    max_quantity: 2,\n    apply_to_quantity: 1,\n    buy_rules_min_quantity: 2,\n  },\n})","handlingStrategy":"validation","validationCode":"const merged = { ...existing.application_method, ...patch }\nif (promoType === \"buyget\" && merged.apply_to_quantity == null) throw new Error(\"apply_to_quantity missing after merge\")","typeGuard":"const isCompleteBuyGetMethod = (am: Record<string, unknown> | undefined): boolean => !!am && am.apply_to_quantity != null && am.buy_rules_min_quantity != null && am.max_quantity != null","tryCatchPattern":"try { await updatePromotions(...) } catch (e) { if (e.type === MedusaError.Types.INVALID_DATA && /apply_to_quantity is a required field/.test(e.message)) { /* merge full application method and retry */ } throw e }","preventionTips":["Merge patches over the fetched application method","Assert buy-get invariants before update","Avoid replacing the application method wholesale"],"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"}