{"record":{"id":"62089c46b888b73a","repo":"medusajs/medusa","slug":"promotion-code-inactivepromocodes-0-is-not-a","errorCode":null,"errorMessage":"Promotion code \"${inactivePromoCodes[0]}\" is not active / Promotion codes \"${inactivePromoCodes.join('\", \"')}\" are not active","messagePattern":"Promotion code \"(.+?)\" is not active / Promotion codes \"(.+?)\" are not active","errorType":"exception","errorClass":"MedusaError","httpStatus":400,"severity":"error","filePath":"packages/core/core-flows/src/draft-order/utils/validation.ts","lineNumber":57,"sourceCode":"        `Promotion codes \"${missingPromoCodes.join('\", \"')}\" not found`\n      )\n    )\n  }\n}\n\nexport function throwIfCodesAreInactive(\n  promo_codes: string[],\n  promotions: PromotionDTO[]\n) {\n  const inactivePromoCodes = promo_codes.filter((code) =>\n    promotions.some(\n      (promotion) =>\n        promotion.code === code && promotion.status !== PromotionStatus.ACTIVE\n    )\n  )\n\n  if (inactivePromoCodes.length > 0) {\n    throw new MedusaError(\n      MedusaError.Types.INVALID_DATA,\n      getMessageByCount(\n        inactivePromoCodes.length,\n        `Promotion code \"${inactivePromoCodes[0]}\" is not active`,\n        `Promotion codes \"${inactivePromoCodes.join('\", \"')}\" are not active`\n      )\n    )\n  }\n}\n","sourceCodeStart":39,"sourceCodeEnd":67,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/core/core-flows/src/draft-order/utils/validation.ts#L39-L67","documentation":"throwIfCodesAreInactive (used by validatePromoCodesToAddStep) checks that every matched promotion has status ACTIVE; adding an inactive/draft/expired promotion code to a draft order throws.","triggerScenarios":"Adding a promo code whose promotion exists but has status inactive/draft/expired (status !== 'ACTIVE') on a draft order.","commonSituations":"Promotion disabled after publish; scheduled promotion not yet active; promotion expired but code still advertised; admin created the promotion but never activated it.","solutions":["Check promotion.status === 'active' before submitting the code","Re-activate/extend the promotion in the admin or via updatePromotions","Provide a friendly 'code no longer active' message to the customer instead of surfacing the raw error"],"exampleFix":"// before\nawait addDraftOrderPromotionsWorkflow(container).run({ input: { order_id, promo_codes: [\"WELCOME10\"] } }) // status=inactive\n\n// after\nconst [promo] = await promotionModule.listPromotions({ code: [\"WELCOME10\"] })\nif (promo?.status === \"active\") {\n  await addDraftOrderPromotionsWorkflow(container).run({ input: { order_id, promo_codes: [\"WELCOME10\"] } })\n} else {\n  throw new Error(\"This code is no longer active\")\n}","handlingStrategy":"validation","validationCode":"const promos = await promotionModule.listPromotions({ code: promo_codes })\nconst inactive = promos.filter((p) => p.status !== \"active\").map((p) => p.code)\nif (inactive.length) throw new Error(`Codes not active: ${inactive.join(\", \")}`)","typeGuard":"const isActivePromo = (p: { status: string }) => p.status === \"active\"","tryCatchPattern":"try { await workflow(scope).run({ input }) } catch (e) { if (/not active/.test(e.message)) { /* show 'code no longer active' message */ } throw e }","preventionTips":["Check promotion status and validity window before advertising codes","Deactivate ads/emails when promotions expire"],"tags":["promotion","promo-code","inactive","draft-order"],"backgroundTag":"promo-code-inactive","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}