mem0ai/mem0 · error · Error
Unsupported filter operator
Error message
Unsupported filter operator: ${op} What it means
When a pgvector SearchFilters value is an object, each key inside it is treated as a comparison operator and looked up in OPERATOR_SQL_MAP. An operator not present in that map throws 'Unsupported filter operator'. Supported operators are those mapped for SQL (eq, ne, gt, gte, lt, lte, in, nin, contains, icontains, etc.).
Solutions
- Correct the operator name to a supported one: eq, ne, gt, gte, lt, lte, in, nin, contains, icontains
- Remove the $ prefix if using Mongo-style operators ('$gte' -> 'gte')
- For operators like 'between', rewrite as two range conditions combined with AND
Example fix
// before
const r = await vs.search(embedding, { filters: { ts: { $gte: 5 } } });
// after
const r = await vs.search(embedding, { filters: { ts: { gte: 5 } } }); Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED = new Set(['eq','ne','gt','gte','lt','lte','in','nin','contains','icontains']);
function validateOperators(filters: any): void {
for (const v of Object.values(filters ?? {})) {
if (v && typeof v === 'object' && !Array.isArray(v)) {
for (const op of Object.keys(v)) {
if (!SUPPORTED.has(op)) throw new Error(`Unsupported operator: ${op}`);
}
}
}
}
validateOperators(filters); Type guard
const isSupportedOperator = (op: string): op is 'eq'|'ne'|'gt'|'gte'|'lt'|'lte'|'in'|'nin'|'contains'|'icontains' => ['eq','ne','gt','gte','lt','lte','in','nin','contains','icontains'].includes(op);
Try / catch
try { await vs.search(vec, { filters }); } catch (e) { if (e instanceof Error && e.message.startsWith('Unsupported filter operator')) { /* strip/replace bad op, retry once */ } throw e; } Prevention
- Type your filters with a shared FilterOperators union so invalid operators fail at compile time
- Do not copy operator syntax between vector store backends — supported sets differ
- Validate externally supplied filter JSON before it reaches the store
When it happens
Trigger: Passing a nested operator object with a typo or unsupported operator, e.g. filters: { ts: { gteq: 5 } }, { tag: { has: 'x' } }, or { f: { between: [1,2] } } — any object-valued filter whose keys are not recognized comparison operators.
Common situations: Typos like 'gteq' or 'lteq'; copying filter syntax from another vector DB (Qdrant/Weaviate style operators) into the pgvector store; assuming Mongo-style '$gte' works here.
Related errors
- Cannot mix range operators
- Invalid filter key ' ': only letters, digits, and…
- Unsupported filter operator
- Unsupported filter operator(s) for field
- Invalid ' ': only letters, digits, and underscores are…
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/e91ea81d82a2a371.
Report an issue: GitHub.
Appendix: source
Thrown at mem0-ts/src/oss/src/vector_stores/pgvector.ts:118
conditions.push("NOT (" + notGroups.join(" OR ") + ")");
}
continue;
}
const safeKey = escapeFilterKey(key);
if (value === "*") {
conditions.push(`payload ? $${paramIndex}`);
values.push(key);
paramIndex++;
continue;
}
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
for (const [op, opValue] of Object.entries(value)) {
const mapping = OPERATOR_SQL_MAP[op];
if (!mapping) {
throw new Error(`Unsupported filter operator: ${op}`);
}
const clause = mapping.template
.replace("%KEY%", safeKey)
.replace("%IDX%", String(paramIndex));
conditions.push(clause);
if (op === "in" || op === "nin") {
values.push((opValue as any[]).map(String));
} else if (op === "contains" || op === "icontains") {
const escaped = String(opValue)
.replace(/\\/g, "\\\\")
.replace(/%/g, "\\%")
.replace(/_/g, "\\_");
values.push(`%${escaped}%`);
} else if (mapping.numeric) {
values.push(Number(opValue));
} else {
values.push(String(opValue));View on GitHub (pinned to 001c235229)