medusajs/medusa · error · MedusaError

application_method.allocation should be either '${allowedAll

Error message

application_method.allocation should be either '${allowedAllocationTypes.join(" OR ")}' when application_method.target_type is either '${allowedAllocationTargetTypes.join(" OR ")}'

What it means

When application_method.target_type is one of the item-level target types (items / shipping_methods), allocation must be 'each' or 'across' (the allowedAllocationTypes). Any other (or missing) allocation for those target types throws INVALID_DATA.

Source

Thrown at packages/modules/promotion/src/utils/validations/application-method.ts:128

        ", "
      )}`
    )
  }

  const allTypes: string[] = Object.values(ApplicationMethodType)

  if (!allTypes.includes(applicationMethodType)) {
    throw new MedusaError(
      MedusaError.Types.INVALID_DATA,
      `application_method.type should be one of ${allTypes.join(", ")}`
    )
  }

  if (
    allowedAllocationTargetTypes.includes(targetType) &&
    !allowedAllocationTypes.includes(allocation || "")
  ) {
    throw new MedusaError(
      MedusaError.Types.INVALID_DATA,
      `application_method.allocation should be either '${allowedAllocationTypes.join(
        " OR "
      )}' when application_method.target_type is either '${allowedAllocationTargetTypes.join(
        " OR "
      )}'`
    )
  }

  const allAllocationTypes: string[] = Object.values(
    ApplicationMethodAllocation
  )

  if (allocation && !allAllocationTypes.includes(allocation)) {
    throw new MedusaError(
      MedusaError.Types.INVALID_DATA,
      `application_method.allocation should be one of ${allAllocationTypes.join(
        ", "

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Set allocation to 'each' (per-item) or 'across' (spread) whenever target_type is items/shipping_methods
  2. Use 'each' for percentage/fixed per-item discounts and 'across' for spread fixed amounts
  3. Make allocation required in the form when an item-level target type is chosen

Example fix

// before
application_method: { type: "percentage", value: 10, target_type: "items" }

// after
application_method: { type: "percentage", value: 10, target_type: "items", allocation: "each" }
Defensive patterns

Strategy: validation

Validate before calling

const allowedAllocationTypes = [ApplicationMethodAllocation.EACH, ApplicationMethodAllocation.ACROSS]
if (["items", "shipping_methods"].includes(targetType) && !allowedAllocationTypes.includes(allocation)) {
  allocation = ApplicationMethodAllocation.EACH
}

Type guard

const isItemLevelAllocationValid = (targetType: string, allocation?: string): boolean => !["items", "shipping_methods"].includes(targetType) || !!allocation && ["each", "across"].includes(allocation)

Try / catch

try { await createPromotions(...) } catch (e) { if (e.type === MedusaError.Types.INVALID_DATA && /allocation should be either/.test(e.message)) { /* set allocation each/across and resubmit */ } throw e }

Prevention

When it happens

Trigger: Creating a promotion with target_type 'items' but omitting allocation, or setting allocation 'once'/'' alongside target_type 'items' or 'shipping_methods'.

Common situations: Assuming allocation is optional, forms with a default of 'once' applied to item-level promos, porting order-level payloads to item-level target types.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27). Data as JSON: /api/errors/83986f8ad12cbce2. Report an issue: GitHub.