{"record":{"id":"9cc7f33257da34d0","repo":"medusajs/medusa","slug":"application-method-max-quantity-is-a-required-fiel","errorCode":null,"errorMessage":"application_method.max_quantity is a required field for Promotion type of ${PromotionType.BUYGET}","messagePattern":"application_method\\.max_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":75,"sourceCode":"  }\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    }\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    }","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/modules/promotion/src/utils/validations/application-method.ts#L57-L93","documentation":"For buy-get promotions, application_method.max_quantity (the cap on discounted items) is required. The BUYGET validation chain throws INVALID_DATA when maxQuantity is not present.","triggerScenarios":"Creating/updating a buyget promotion whose application_method lacks max_quantity (after apply_to_quantity and buy_rules_min_quantity passed).","commonSituations":"Assuming max_quantity is optional (it is optional for other types but mandatory for buyget), migration scripts copying non-buyget payloads, UI hiding the field by default.","solutions":["Add max_quantity to the buy-get application method; commonly equal to apply_to_quantity","Remember max_quantity >= apply_to_quantity is separately enforced — set it consistently","Include the field in seeds and imports for all buyget promotions"],"exampleFix":"// before\napplication_method: { ..., apply_to_quantity: 1, buy_rules_min_quantity: 2 }\n\n// after\napplication_method: { ..., apply_to_quantity: 1, buy_rules_min_quantity: 2, max_quantity: 1 }","handlingStrategy":"validation","validationCode":"if (type === \"buyget\" && !isDefined(applicationMethod.max_quantity)) {\n  applicationMethod.max_quantity = applicationMethod.apply_to_quantity ?? 1\n}","typeGuard":"const hasMaxQuantity = (am: { max_quantity?: number | null }): boolean => am.max_quantity !== undefined && am.max_quantity !== null","tryCatchPattern":"try { await updatePromotions(...) } catch (e) { if (e.type === MedusaError.Types.INVALID_DATA && /max_quantity is a required field/.test(e.message)) { /* default max_quantity = apply_to_quantity and retry */ } throw e }","preventionTips":["Default max_quantity to apply_to_quantity for buy-get","Include max_quantity in seeds/imports","Remember it is required only for buyget"],"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"}