mem0ai/mem0 · error

Unsupported metadata filter operator: ${operator}

Error message

Unsupported metadata filter operator: ${operator}

What it means

Thrown while processing config.metadataFilters (in add/search filter preprocessing) when a condition object uses an operator key outside the supported map: equals, neq, gt, gte, lt, lte, in, nin, contains, icontains. The operator names are passed through to the vector store, so unknown operators are rejected rather than silently dropped.

Source

Thrown at mem0-ts/src/oss/src/memory/index.ts:2141

        ne: "ne",
        gt: "gt",
        gte: "gte",
        lt: "lt",
        lte: "lte",
        in: "in",
        nin: "nin",
        contains: "contains",
        icontains: "icontains",
      };

      for (const [operator, value] of Object.entries(condition)) {
        if (operator in operatorMap) {
          if (!result[key]) {
            result[key] = {};
          }
          result[key][operatorMap[operator]] = value;
        } else {
          throw new Error(`Unsupported metadata filter operator: ${operator}`);
        }
      }
      return result;
    };

    for (const [key, value] of Object.entries(metadataFilters)) {
      if (key === "AND") {
        // Logical AND: combine multiple conditions
        if (!Array.isArray(value)) {
          throw new Error("AND operator requires a list of conditions");
        }
        for (const condition of value) {
          for (const [subKey, subValue] of Object.entries(condition)) {
            Object.assign(processedFilters, processCondition(subKey, subValue));
          }
        }
      } else if (key === "OR") {
        // Logical OR: Pass through to vector store for implementation-specific handling

View on GitHub (pinned to 001c235229)

Solutions

  1. Use only the supported operators: equals, neq, gt, gte, lt, lte, in, nin, contains, icontains
  2. Replace eq with equals and like with icontains (case-insensitive contains)
  3. If building filters dynamically, validate operator keys against the allowed set before calling the SDK

Example fix

// before
filters: { user_id: 'u1', AND: [{ created_at: { eq: '2024-01-01' } }] }

// after
filters: { user_id: 'u1', AND: [{ created_at: { equals: '2024-01-01' } }] }
Defensive patterns

Strategy: type-guard

Validate before calling

const OPS = new Set(['equals','neq','gt','gte','lt','lte','in','nin','contains','icontains']);
function assertOperators(filters: Record<string, unknown>) {
  for (const v of Object.values(filters)) {
    for (const op of Object.keys(v as object)) {
      if (!OPS.has(op)) throw new Error(`unknown filter operator: ${op}`);
    }
  }
}

Type guard

const isSupportedOperator = (op: string): op is 'equals'|'neq'|'gt'|'gte'|'lt'|'lte'|'in'|'nin'|'contains'|'icontains' =>
  ['equals','neq','gt','gte','lt','lte','in','nin','contains','icontains'].includes(op as never);

Prevention

When it happens

Trigger: Writing a condition like { created_at: { eq: '2024-01-01' } } (eq is not supported — it is equals), or { tag: { like: 'x' } }, or { count: { >: 5 } } (symbol keys are not operators).

Common situations: Translating SQL/Mongo intuition (eq, like, $gt) to Mem0's operator names; version drift if operator names changed between releases; typos in dynamic filter construction.

Related errors


AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15). Data as JSON: /api/errors/b00fdfc95ad5f020. Report an issue: GitHub.