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
- Use only the operators listed in the error message
- Map legacy symbols: = -> eq, != -> neq, > -> gt, etc.
- 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
- Map legacy symbols (=, !=, >, <) to canonical tokens in an adapter layer
- Pin and read the operator list from the module version you use
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
- Rule must have an attribute, an operator and a value
- Rule value must be an array for in/nin operators
- Rule value must be a string, bool, number value for the sele
- Invalid rule attribute - ${ruleAttributeId}
- The following shipping options do not exist: ${Array.from(mi
AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27).
Data as JSON: /api/errors/5f697b10030f0658.
Report an issue: GitHub.