medusajs/medusa · error · MedusaError

application_method.allocation 'once' is not compatible with

Error message

application_method.allocation 'once' is not compatible with target_type 'order'

What it means

Allocation 'once' is incompatible with target_type 'order'. An order-level application method applies to the whole order by definition, so 'once' (single application) is rejected with INVALID_DATA; use allocation 'across' for order target types.

Source

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

  if (
    allocation &&
    allowedAllocationForQuantity.includes(allocation) &&
    !isDefined(maxQuantity)
  ) {
    throw new MedusaError(
      MedusaError.Types.INVALID_DATA,
      `application_method.max_quantity is required when application_method.allocation is '${allowedAllocationForQuantity.join(
        " OR "
      )}'`
    )
  }

  if (
    allocation === ApplicationMethodAllocation.ONCE &&
    targetType === ApplicationMethodTargetType.ORDER
  ) {
    throw new MedusaError(
      MedusaError.Types.INVALID_DATA,
      `application_method.allocation 'once' is not compatible with target_type 'order'`
    )
  }
}

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Use allocation 'across' with target_type 'order'
  2. Omit/choose allocation appropriate to the target type (order-level methods typically use 'across')
  3. Validate the allocation/target_type pair in the form logic

Example fix

// before
application_method: { type: "fixed", value: 20, target_type: "order", allocation: "once" }

// after
application_method: { type: "fixed", value: 20, target_type: "order", allocation: "across" }
Defensive patterns

Strategy: validation

Validate before calling

if (targetType === ApplicationMethodTargetType.ORDER && allocation === ApplicationMethodAllocation.ONCE) {
  allocation = ApplicationMethodAllocation.ACROSS
}

Type guard

const isAllocationTargetCompatible = (allocation: string | undefined, targetType: string | undefined): boolean => !(allocation === "once" && targetType === "order")

Try / catch

try { await createPromotions(...) } catch (e) { if (e.type === MedusaError.Types.INVALID_DATA && /'once' is not compatible with target_type 'order'/.test(e.message)) { /* switch to across and resubmit */ } throw e }

Prevention

When it happens

Trigger: Creating a promotion with target_type 'order' and allocation 'once' — commonly an order-level fixed discount payload that copied 'once' from another promo.

Common situations: Misreading 'once' as 'one order', form defaults, integrations applying the same allocation to all target types.

Related errors


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