{"record":{"id":"e01140bc8fecea28","repo":"medusajs/medusa","slug":"application-method-value-should-be-a-percentage-nu","errorCode":null,"errorMessage":"Application Method value should be a percentage number between 0 and 100","messagePattern":"Application Method value should be a percentage number between 0 and 100","errorType":"validation","errorClass":"MedusaError","httpStatus":400,"severity":"error","filePath":"packages/modules/promotion/src/utils/validations/application-method.ts","lineNumber":53,"sourceCode":") {\n  const applicationMethod = promotion?.application_method || {}\n  const buyRulesMinQuantity =\n    data.buy_rules_min_quantity || applicationMethod?.buy_rules_min_quantity\n  const applyToQuantity =\n    data.apply_to_quantity || applicationMethod?.apply_to_quantity\n  const targetType = data.target_type || applicationMethod?.target_type\n  const type = data.type || applicationMethod?.type\n  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      )","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/modules/promotion/src/utils/validations/application-method.ts#L35-L71","documentation":"validateApplicationMethodAttributes enforces that percentage application methods have a value in (0, 100]. A value <= 0 or > 100 throws INVALID_DATA, blocking promotion create/update (createPromotions_/updatePromotions_).","triggerScenarios":"Creating or updating a promotion with application_method.type 'percentage' and value 0, negative, or e.g. 150; also passing value as a decimal string the BigNumber math still evaluates out of range.","commonSituations":"Forms allowing 0% or >100% discounts, importing legacy promo data with 0 as sentinel for 'no discount', unit confusion (passing basis points 1500 instead of 15%).","solutions":["Clamp/validate the percentage to 1–100 in the client form before submission","If a free (100%-off-like) discount is needed, use value 100 exactly — do not exceed it","Sanitize imported data: convert basis points by dividing by 100, treat 0 as invalid and skip"],"exampleFix":"// before\nawait promotionModule.createPromotions({ code: \"SUMMER\", type: \"standard\", application_method: { type: \"percentage\", value: 150, target_type: \"items\", allocation: \"each\" } })\n\n// after\nawait promotionModule.createPromotions({ code: \"SUMMER\", type: \"standard\", application_method: { type: \"percentage\", value: 50, target_type: \"items\", allocation: \"each\" } })","handlingStrategy":"validation","validationCode":"if (applicationMethod.type === \"percentage\") {\n  const v = Number(applicationMethod.value)\n  if (!(v > 0 && v <= 100)) throw new Error(\"percentage must be in (0, 100]\")\n}","typeGuard":"const isValidPercentage = (am: { type?: string; value?: number | string }): boolean => am.type !== \"percentage\" || (Number(am.value) > 0 && Number(am.value) <= 100)","tryCatchPattern":"try { await createPromotions(...) } catch (e) { if (e.type === MedusaError.Types.INVALID_DATA && /percentage number between 0 and 100/.test(e.message)) { /* clamp value and resubmit */ } throw e }","preventionTips":["Clamp percentage inputs in forms (min 1, max 100)","Convert basis points to percent before import","Treat 0 as invalid discount data"],"tags":["promotion","application-method","percentage","validation","medusa"],"backgroundTag":"value-out-of-range","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}