mem0ai/mem0 · error · Error

Unsupported Oracle logical filter operator: ${key}

Error message

Unsupported Oracle logical filter operator: ${key}

What it means

Any key starting with '$' that is not one of the recognized logical operators ($and, $or, $not) is rejected. LOGICAL_OPERATORS also accepts the uppercase forms AND/OR/NOT, but every other dollar-prefixed key at group level is unsupported and would otherwise be misinterpreted as a metadata field name.

Source

Thrown at mem0-ts/src/oss/src/vector_stores/oracledb.ts:279

        throw new Error(
          `Logical filter operator '${key}' requires a non-empty array`,
        );
      }
      const nested = value.map((condition) =>
        buildFilterGroup(condition, binds),
      );
      if (logicalOperator === "not") {
        clauses.push(`NOT (${nested.join(" OR ")})`);
      } else {
        clauses.push(
          `(${nested.join(logicalOperator === "and" ? " AND " : " OR ")})`,
        );
      }
      continue;
    }

    if (key.startsWith("$")) {
      throw new Error(`Unsupported Oracle logical filter operator: ${key}`);
    }

    clauses.push(buildFieldCondition(key, value, binds));
  }

  return clauses.length === 1 ? clauses[0] : `(${clauses.join(" AND ")})`;
}

export function buildWhereClause(
  filters?: SearchFilters,
): [string, Record<string, any>] {
  if (!filters || Object.keys(filters).length === 0) {
    return ["", {}];
  }
  const binds: Record<string, any> = {};
  return [`WHERE ${buildFilterGroup(filters, binds)}`, binds];
}

View on GitHub (pinned to 001c235229)

Solutions

  1. Rewrite $nor as { $not: [...conditions ] } (NOT over the OR-join).
  2. Move logical operators to the group level: { $or: [{ a: 1 }, { b: 2 }] }, never nested inside a field's operator object.
  3. Remove MongoDB-only operators ($expr, $where, $jsonSchema) — express them with supported comparisons or filter client-side.
  4. Check for typos: $AND/$OR (mixed case) are not recognized; use $and/$or or AND/OR.

Example fix

// before
filters = { $nor: [{ a: 1 }, { b: 2 }] };

// after
filters = { $not: [{ a: 1 }, { b: 2 }] }; // NOT (a==1 OR b==2)
Defensive patterns

Strategy: validation

Validate before calling

const LOGICAL = new Set(['$and','$or','$not','AND','OR','NOT']);
function assertKnownLogicalKeys(filters: any): void {
  if (!filters || typeof filters !== 'object') return;
  for (const key of Object.keys(filters)) {
    if (key.startsWith('$') && !LOGICAL.has(key)) throw new RangeError(`Unsupported logical operator '${key}'`);
    const v = (filters as any)[key];
    if (Array.isArray(v)) v.forEach(assertKnownLogicalKeys);
  }
}

Type guard

const isSupportedLogicalOperator = (k: string): k is '$and' | '$or' | '$not' | 'AND' | 'OR' | 'NOT' =>
  ['$and','$or','$not','AND','OR','NOT'].includes(k);

Try / catch

try { await memory.search('q', { filters }); } catch (e) { if (e instanceof Error && e.message.includes('Unsupported Oracle logical filter operator')) { /* rewrite $nor→$not(...), drop $expr, or filter client-side */ } else throw e; }

Prevention

When it happens

Trigger: { $nor: [...] }, { $expr: ... } at group level, or nesting errors like { user_id: { $and: [...] } } where $and appears as a field operator — in that position $and is not in FIELD_OPERATORS and surfaces via error 260 instead; group-level $nor/$where/$expr hit this error directly.

Common situations: Copying MongoDB query syntax ($nor, $expr, $jsonSchema) into search filters; putting logical operators one level too deep under a field key; mixing filter dialects between mem0 backends.

Related errors


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