mem0ai/mem0 · error · Error
Unsupported filter operator '${op}' for Pinecone
Error message
Unsupported filter operator '${op}' for Pinecone What it means
When translating mem0 SearchFilters to Pinecone metadata filter syntax, each operator in an object-valued filter is switched over. Recognized operators (eq, ne, gt, gte, lt, lte, in, nin) are mapped; contains/icontains are skipped with a warning because Pinecone metadata filtering does not support substring matching; any other operator throws this error.
Source
Thrown at mem0-ts/src/oss/src/vector_stores/pinecone.ts:227
pineconeOps["$lt"] = opVal;
break;
case "lte":
pineconeOps["$lte"] = opVal;
break;
case "in":
pineconeOps["$in"] = opVal;
break;
case "nin":
pineconeOps["$nin"] = opVal;
break;
case "contains":
case "icontains":
console.warn(
`Filter operator '${op}' is not supported by Pinecone metadata filters; skipping.`,
);
break;
default:
throw new Error(
`Unsupported filter operator '${op}' for Pinecone`,
);
}
}
if (Object.keys(pineconeOps).length > 0) {
result[key] = pineconeOps;
}
continue;
}
result[key] = { $eq: value };
}
return Object.keys(result).length > 0 ? result : undefined;
}
async insert(
vectors: number[][],View on GitHub (pinned to 001c235229)
Solutions
- Use only translated operators: eq, ne, gt, gte, lt, lte, in, nin
- Replace contains/icontains substring filters with exact-match (eq/in) on pre-normalized metadata values, since Pinecone cannot do substring matching
- Remove Mongo '$' prefixes from operator names
- If you need contains semantics, store a lowercased exact field (e.g. tag_exact) and filter with eq
Example fix
// before
const r = await vs.search(vec, { filters: { tag: { $regex: 'news' } } });
// after
const r = await vs.search(vec, { filters: { tag: { in: ['news', 'world'] } } }); Defensive patterns
Strategy: validation
Validate before calling
const PINECONE_OPS = new Set(['eq','ne','gt','gte','lt','lte','in','nin']);
function validatePineconeFilters(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 (!PINECONE_OPS.has(op)) throw new Error(`Operator '${op}' unsupported on Pinecone`);
}
}
}
}
validatePineconeFilters(filters); Type guard
const isPineconeOperator = (op: string): boolean => ['eq','ne','gt','gte','lt','lte','in','nin'].includes(op);
Try / catch
try { await vs.search(vec, { filters }); } catch (e) { if (e instanceof Error && e.message.includes('for Pinecone')) { /* reduce filter to supported ops, retry */ } throw e; } Prevention
- Remember contains/icontains are silently skipped on Pinecone — design metadata for exact matching
- Keep per-backend filter builders instead of one shared filter object across stores
- Unit-test filter translation for every backend you support
When it happens
Trigger: Passing filters like { tag: { has: 'x' } }, { f: { exists: true } }, or Mongo-style { '$gte': 1 } to a search on the Pinecone store; using an operator supported by pgvector/qdrant but not translated here.
Common situations: Sharing filter-building code across multiple vector store backends where one supports extra operators; typos in operator names; copying filter examples from Qdrant-style docs.
Related errors
- Unsupported filter operator: ${op}
- Cannot mix range operators (${ops.filter((o) => rangeOps.inc
- Unsupported filter operator(s) for field '${key}': ${ops.joi
- Invalid filter key '${key}': only letters, digits, and under
- ${key} filter value must be a list of filter dicts, got ${ty
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/86ee9b1d89130e21.
Report an issue: GitHub.