medusajs/medusa · error · MedusaError

Rule operator ${rule.operator} is not supported. Must be one

Error message

Rule operator ${rule.operator} is not supported. Must be one of ${availableOperators.join(", ")}

What it means

The rule operator must be one of the supported operators exposed by the fulfillment module (the availableOperators list — eq, neq, gt, gte, lt, lte, in, nin). Any other string throws INVALID_DATA listing the valid options.

Source

Thrown at packages/modules/fulfillment/src/utils/utils.ts:121

    )
  }

  if (!isString(rule.attribute)) {
    throw new MedusaError(
      MedusaError.Types.INVALID_DATA,
      "Rule attribute must be a string"
    )
  }

  if (!isString(rule.operator)) {
    throw new MedusaError(
      MedusaError.Types.INVALID_DATA,
      "Rule operator must be a string"
    )
  }

  if (!availableOperators.includes(rule.operator as RuleOperator)) {
    throw new MedusaError(
      MedusaError.Types.INVALID_DATA,
      `Rule operator ${
        rule.operator
      } is not supported. Must be one of ${availableOperators.join(", ")}`
    )
  }

  if (rule.operator === RuleOperator.IN || rule.operator === RuleOperator.NIN) {
    if (!Array.isArray(rule.value)) {
      throw new MedusaError(
        MedusaError.Types.INVALID_DATA,
        "Rule value must be an array for in/nin operators"
      )
    }
  } else {
    if (Array.isArray(rule.value) || isObject(rule.value)) {
      throw new MedusaError(
        MedusaError.Types.INVALID_DATA,

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Use only the operators listed in the error message
  2. Map legacy symbols: = -> eq, != -> neq, > -> gt, etc.
  3. If you need 'in'/'nin', supply an array value

Example fix

// before
rules: [{ attribute: 'cart_total', operator: '>', value: 100 }]
// after
rules: [{ attribute: 'cart_total', operator: 'gt', value: 100 }]
Defensive patterns

Strategy: validation

Validate before calling

const OPERATORS = ['eq','neq','gt','gte','lt','lte','in','nin']
if (!OPERATORS.includes(rule.operator)) throw new Error(`Unsupported operator: ${rule.operator}`)

Type guard

type RuleOperatorT = 'eq'|'neq'|'gt'|'gte'|'lt'|'lte'|'in'|'nin'
const isSupportedOperator = (o: string): o is RuleOperatorT => OPERATORS.includes(o)

Prevention

When it happens

Trigger: Using operators like '=', '!=' , 'contains', or '>' instead of the canonical tokens; version drift where operators were renamed/added.

Common situations: Porting rule definitions from another system or an older Medusa version; hand-writing operators from memory.

Related errors


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