mem0ai/mem0 · error · Error
Unsupported filter operator(s) for field '${key}': ${ops.joi
Error message
Unsupported filter operator(s) for field '${key}': ${ops.join(", ")}. Supported operators: ${supportedOps.join(", ")} What it means
The Qdrant filter builder falls through to this error when an object-valued filter field contains operators outside the supported set: eq, ne, gt, gte, lt, lte, in, nin, contains, icontains. It exists because Qdrant's filter model has no translation for other operators.
Source
Thrown at mem0-ts/src/oss/src/vector_stores/qdrant.ts:205
if ("contains" in value || "icontains" in value) {
const text = value.contains || value.icontains;
return { key, match: { text } };
}
// Unknown operator - treat as nested object for simple match
const supportedOps = [
"eq",
"ne",
"gt",
"gte",
"lt",
"lte",
"in",
"nin",
"contains",
"icontains",
];
throw new Error(
`Unsupported filter operator(s) for field '${key}': ${ops.join(", ")}. ` +
`Supported operators: ${supportedOps.join(", ")}`,
);
}
/**
* Create a Filter object from the provided filters.
* Supports logical operators (AND, OR, NOT) and comparison operators.
*/
private createFilter(filters?: SearchFilters): QdrantFilter | undefined {
if (!filters || Object.keys(filters).length === 0) return undefined;
// Normalize $or/$not/$and → OR/NOT/AND and deduplicate
const normalized: Record<string, any> = {};
for (const [key, value] of Object.entries(filters)) {
const normKey = KEY_MAP[key] || key;
if (!(normKey in normalized)) {
normalized[normKey] = value;View on GitHub (pinned to 001c235229)
Solutions
- Rewrite the filter using only supported operators: eq, ne, gt, gte, lt, lte, in, nin, contains, icontains
- Remove '$' prefixes from Mongo-style operators
- Express 'between' as { gte: lo, lte: hi } and 'hasAll' as a nested contains/in combination or separate AND entries
Example fix
// before
const r = await vs.search(vec, { filters: { age: { between: [20, 30] } } });
// after
const r = await vs.search(vec, { filters: { age: { gte: 20, lte: 30 } } }); Defensive patterns
Strategy: validation
Validate before calling
const QDRANT_OPS = new Set(['eq','ne','gt','gte','lt','lte','in','nin','contains','icontains']);
function validateQdrantFilters(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 (!QDRANT_OPS.has(op)) throw new Error(`Operator '${op}' unsupported on Qdrant`);
}
}
}
}
validateQdrantFilters(filters); Type guard
type QdrantOp = 'eq'|'ne'|'gt'|'gte'|'lt'|'lte'|'in'|'nin'|'contains'|'icontains'; const isQdrantOp = (op: string): op is QdrantOp => ['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.includes('Unsupported filter operator')) { /* rewrite to supported ops, retry */ } throw e; } Prevention
- Strip Mongo '$' prefixes at your API boundary
- Express 'between' as gte+lte pairs
- Share a typed filter schema between client and server
When it happens
Trigger: Passing filters like { f: { between: [1, 2] } }, { f: { $gte: 1 } }, { f: { hasAll: [...] } }, or an object with typo'd operator names such as { f: { gteq: 1 } }.
Common situations: Porting filter code from Mongo/Postgres syntax; typos in operator keys; combining API request payloads with extra keys inside operator objects.
Related errors
- Cannot mix range operators (${ops.filter((o) => rangeOps.inc
- Unsupported filter operator: ${op}
- Unsupported filter operator '${op}' for Pinecone
- ${key} filter value must be a list of filter dicts, got ${ty
- ${key} filter list item at index ${i} must be a dict, got ${
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/84f1e9c5d766074b.
Report an issue: GitHub.