{"record":{"id":"85a626cfab556194","repo":"medusajs/medusa","slug":"rule-must-have-an-attribute-an-operator-and-a-val","errorCode":null,"errorMessage":"Rule must have an attribute, an operator and a value","messagePattern":"Rule must have an attribute, an operator and a value","errorType":"validation","errorClass":"MedusaError","httpStatus":400,"severity":"error","filePath":"packages/modules/fulfillment/src/utils/utils.ts","lineNumber":100,"sourceCode":"    const { attribute, operator, value } = rule\n    const contextValue = pickValueFromObject(attribute, context)\n\n    return operatorsPredicate[operator](\n      `${contextValue}`,\n      value as string & string[]\n    )\n  }\n\n  return loopComparator.apply(rules, [predicate])\n}\n\n/**\n * Validate contextValue rule object\n * @param rule\n */\nexport function validateRule(rule: Record<string, unknown>): boolean {\n  if (!rule.attribute || !rule.operator || !rule.value) {\n    throw new MedusaError(\n      MedusaError.Types.INVALID_DATA,\n      \"Rule must have an attribute, an operator and a value\"\n    )\n  }\n\n  if (!isString(rule.attribute)) {\n    throw new MedusaError(\n      MedusaError.Types.INVALID_DATA,\n      \"Rule attribute must be a string\"\n    )\n  }\n\n  if (!isString(rule.operator)) {\n    throw new MedusaError(\n      MedusaError.Types.INVALID_DATA,\n      \"Rule operator must be a string\"\n    )\n  }","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/modules/fulfillment/src/utils/utils.ts#L82-L118","documentation":"validateRule checks that a shipping-option rule object has attribute, operator, and value; missing any of the three throws INVALID_DATA. Note value must be truthy, so empty-string or 0 values are also rejected.","triggerScenarios":"create/updateShippingOptions with rules like { attribute: 'iso', operator: 'eq' } (no value), or passing rules: [null] / partially built objects.","commonSituations":"Dynamic rule builders that submit incomplete forms; JSON payloads where value key is omitted.","solutions":["Ensure every rule has non-empty attribute, operator, and value","Guard before submit: rule.attribute && rule.operator && rule.value !== undefined && rule.value !== ''","For in/nin use a non-empty array as value"],"exampleFix":"// before\nrules: [{ attribute: 'cart_total', operator: 'gt' }]\n// after\nrules: [{ attribute: 'cart_total', operator: 'gt', value: 100 }]","handlingStrategy":"validation","validationCode":"const isCompleteRule = (r: any) => !!r?.attribute && !!r?.operator && r?.value !== undefined && r?.value !== '' && !(Array.isArray(r.value) && !r.value.length)","typeGuard":"const isCompleteRule = (r: any): r is { attribute: string; operator: string; value: unknown } => !!r?.attribute && !!r?.operator && !!r?.value","tryCatchPattern":null,"preventionTips":["Validate rules client-side before submit","Remember 0 and '' are rejected — use explicit non-empty values"],"tags":["fulfillment","rules","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}