medusajs/medusa · error · MedusaError
Promotion code "${missingPromoCodes[0]}" not found / Promoti
Error message
Promotion code "${missingPromoCodes[0]}" not found / Promotion codes "${missingPromoCodes.join('", "')}" not found What it means
throwIfCodesAreMissing (used by validatePromoCodesToAddStep/ToRemoveStep) verifies every promo code passed exists among the fetched promotions; missing codes throw INVALID_DATA.
Source
Thrown at packages/core/core-flows/src/draft-order/utils/validation.ts:34
"Order is not a draft"
)
}
}
function getMessageByCount(count: number, singular: string, plural: string) {
return count === 1 ? singular : plural
}
export function throwIfCodesAreMissing(
promo_codes: string[],
promotions: PromotionDTO[]
) {
const missingPromoCodes = promo_codes.filter(
(code) => !promotions.some((promotion) => promotion.code === code)
)
if (missingPromoCodes.length > 0) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
getMessageByCount(
missingPromoCodes.length,
`Promotion code "${missingPromoCodes[0]}" not found`,
`Promotion codes "${missingPromoCodes.join('", "')}" not found`
)
)
}
}
export function throwIfCodesAreInactive(
promo_codes: string[],
promotions: PromotionDTO[]
) {
const inactivePromoCodes = promo_codes.filter((code) =>
promotions.some(
(promotion) =>
promotion.code === code && promotion.status !== PromotionStatus.ACTIVEView on GitHub (pinned to 5e06e544a2)
Solutions
- Verify each code against promotion.listPromotions({ code: [...] }) before calling the workflow
- Create or re-enable the promotion in this environment
- Normalize/validate user-entered codes (trim, case) against the code list
Example fix
// before
await addDraftOrderPromotionsWorkflow(container).run({ input: { order_id, promo_codes: ["WELCOME10"] } }) // code deleted
// after
const promos = await promotionModule.listPromotions({ code: ["WELCOME10"] })
if (promos.length === 1) {
await addDraftOrderPromotionsWorkflow(container).run({ input: { order_id, promo_codes: ["WELCOME10"] } })
} else {
throw new Error("Invalid promo code")
} Defensive patterns
Strategy: validation
Validate before calling
const promos = await promotionModule.listPromotions({ code: promo_codes })
const missing = promo_codes.filter((c) => !promos.some((p) => p.code === c))
if (missing.length) throw new Error(`Unknown codes: ${missing.join(", ")}`) Try / catch
try { await workflow(scope).run({ input }) } catch (e) { if (/Promotion code(s)? .* not found/.test(e.message)) { /* show friendly invalid-code message */ } throw e } Prevention
- Trim and case-normalize user-entered codes
- Validate codes against listPromotions before submission
When it happens
Trigger: Adding or removing promo codes on a draft order with one or more codes that don't exist in the promotion module (typo, deleted promotion, wrong environment).
Common situations: User pastes an old/expired code that was deleted; promotion created in a different environment (staging vs prod); case-sensitivity mismatch; client sends code trimmed incorrectly.
Related errors
- Promotion code "${inactivePromoCodes[0]}" is not active / Pr
- A shipping method with id ${input.shipping_method_id} was no
- No item found for order ${input.order_id} in order change ${
- No shipping method found for order ${input.order_id} in orde
- No request to add item for order ${input.order_id} in order
AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27).
Data as JSON: /api/errors/8dd4011588b95ff6.
Report an issue: GitHub.