medusajs/medusa · error · MedusaError

invalid_data

invalid_data

Error message

invalidOperatorError

What it means

When upserting price list rules with array values, each rule object must carry an operator that exists in the allowed rule operator set (e.g. 'eq', 'gt', 'lt', 'gte', 'lte', 'in'...). Using an unknown operator throws INVALID_DATA with the shared invalidOperatorError message.

Source

Thrown at packages/modules/pricing/src/services/pricing-module.ts:938

    const existingPricesMap = new Map<string, PricingTypes.PriceDTO>()
    Array.from(existingPrices ?? []).forEach((price) => {
      existingPricesMap.set(hashPrice(price), price)
    })

    const ruleOperatorsSet = new Set<PricingRuleOperatorValues>(
      Object.values(PricingRuleOperator)
    )
    const validOperatorsList = Array.from(ruleOperatorsSet).join(", ")
    const invalidOperatorError = `operator should be one of ${validOperatorsList}`

    data?.forEach((price) => {
      const cleanRules = price.rules ? removeNullish(price.rules) : {}

      const rules = Object.entries(cleanRules).flatMap(([attribute, value]) => {
        if (Array.isArray(value)) {
          return value.map((customRule) => {
            if (!ruleOperatorsSet.has(customRule.operator)) {
              throw new MedusaError(
                MedusaError.Types.INVALID_DATA,
                invalidOperatorError
              )
            }

            if (typeof customRule.value !== "number") {
              throw new MedusaError(
                MedusaError.Types.INVALID_DATA,
                `value should be a number`
              )
            }

            return {
              attribute,
              operator: customRule.operator,
              // TODO: we throw above if value is not a number, but the model expect the value to be a string
              value: customRule.value.toString(),
            }

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Use only supported operators (eq, ne, gt, gte, lt, lte, in) — check ruleOperatorsSet in the pricing module for the exact list
  2. Fix typos such as 'equals' → 'eq' or '>=' → 'gte'
  3. If building rules dynamically, validate the operator against an allowlist before calling the API

Example fix

// before
rules: { region_id: [{ operator: 'equals', value: 'reg_123' }] }

// after
rules: { region_id: [{ operator: 'eq', value: 'reg_123' }] }
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED_OPERATORS = ['eq','ne','gt','gte','lt','lte','in'] as const
const normalizeOperator = (op: string) =>
  ({ equals: 'eq', '=': 'eq', '>=': 'gte', '<=': 'lte' } as Record<string,string>)[op] ?? op

const rules = Object.fromEntries(
  Object.entries(rawRules).map(([k, v]) => [
    k,
    Array.isArray(v)
      ? v.map((r) => ({ ...r, operator: normalizeOperator(r.operator) }))
      : v,
  ])
)
// verify before calling
for (const v of Object.values(rules)) {
  if (Array.isArray(v)) v.forEach((r) => {
    if (!ALLOWED_OPERATORS.includes(r.operator)) throw new Error(`Bad operator: ${r.operator}`)
  })
}

Type guard

const isRuleOperator = (op: unknown): op is 'eq'|'ne'|'gt'|'gte'|'lt'|'lte'|'in' =>
  typeof op === 'string' && ['eq','ne','gt','gte','lt','lte','in'].includes(op)

Prevention

When it happens

Trigger: Calling updatePriceListRules / addPriceListRules-style APIs (upserting prices with rules) where a rule value is an array of { operator, value } objects and operator is misspelled or unsupported, e.g. 'equals' instead of 'eq'.

Common situations: Porting code from an older Medusa version where rules were plain key-value maps, guessing operator names, or string typos in dynamic rule building.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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