mem0ai/mem0 · error · ValueError
Unsupported metadata filter operator: {operator}
Error message
Unsupported metadata filter operator: {operator} What it means
Raised inside _process_metadata_filters (used by search()/get_all() when advanced operators are detected) when a condition dict uses an operator key outside the supported set. Supported operators are exactly: eq, ne, gt, gte, lt, lte, in, nin, contains, icontains. Anything else — 'gteq', 'between', 'regex', 'exists', '$gte' with a dollar prefix, or a typo — raises this ValueError naming the bad operator.
Source
Thrown at mem0/memory/main.py:1556
# Simple equality: {"key": "value"}
if condition == "*":
# Wildcard: match everything for this field (implementation depends on vector store)
return {key: "*"}
return {key: condition}
result = {}
for operator, value in condition.items():
# Map platform operators to universal format that can be translated by each vector store
operator_map = {
"eq": "eq", "ne": "ne", "gt": "gt", "gte": "gte",
"lt": "lt", "lte": "lte", "in": "in", "nin": "nin",
"contains": "contains", "icontains": "icontains"
}
if operator in operator_map:
result.setdefault(key, {})[operator_map[operator]] = value
else:
raise ValueError(f"Unsupported metadata filter operator: {operator}")
return result
def merge_filters(target: Dict[str, Any], source: Dict[str, Any]) -> None:
"""Merge source into target, deep-merging nested operator dicts for the same key."""
for key, value in source.items():
if key in target and isinstance(target[key], dict) and isinstance(value, dict):
target[key].update(value)
else:
target[key] = value
for key, value in metadata_filters.items():
if key == "AND":
# Logical AND: combine multiple conditions
if not isinstance(value, list):
raise ValueError("AND operator requires a list of conditions")
for condition in value:
for sub_key, sub_value in condition.items():
merge_filters(processed_filters, process_condition(sub_key, sub_value))View on GitHub (pinned to 001c235229)
Solutions
- Replace the operator with one of the ten supported names, lowercase, no $ prefix (e.g. $gte -> gte, $in -> in).
- Express 'between' as two conditions merged under AND: {'AND': [{'ts': {'gte': 1}}, {'ts': {'lte': 2}}]}.
- Validate filter dicts against the supported set before calling search/get_all (see validation code in the defense section).
- For regex-like matching, use contains/icontains for substring and case-insensitive substring respectively.
Example fix
# before
filters = {"user_id": "u1", "score": {"$gte": 0.5}}
# after
filters = {"user_id": "u1", "score": {"gte": 0.5}} Defensive patterns
Strategy: validation
Validate before calling
SUPPORTED_OPS = {"eq", "ne", "gt", "gte", "lt", "lte", "in", "nin", "contains", "icontains"}
LOGICAL_OPS = {"AND", "OR", "NOT"}
def validate_filters(filters):
for key, value in filters.items():
if key in LOGICAL_OPS:
if not isinstance(value, list):
raise ValueError(f"{key} must be a list")
for cond in value:
validate_filters(cond)
elif isinstance(value, dict):
bad = set(value) - SUPPORTED_OPS
if bad:
raise ValueError(f"unsupported operators: {bad}; supported: {sorted(SUPPORTED_OPS)}") Type guard
def is_supported_operator(op: str) -> bool:
return op in {"eq", "ne", "gt", "gte", "lt", "lte", "in", "nin", "contains", "icontains"} Prevention
- Use lowercase operators without $ prefixes — this is not Mongo syntax.
- Express ranges as {'AND': [{'k': {'gte': lo}}, {'k': {'lte': hi}}]}.
- Validate LLM-generated filter dicts against the supported set before passing them in.
- Use contains/icontains for substring matching; there is no regex operator.
When it happens
Trigger: filters={'user_id':'u1','score':{'$gte':0.5}} using Mongo-style $-prefixed operators; {'ts':{'between':[1,2]}}; {'name':{'regex':'^a'}}; typo 'gte ' with whitespace or 'GTE' uppercase (matching is case-sensitive); copying filter syntax from Pinecone/Qdrant/Mongo docs into mem0 filters.
Common situations: Developers fluent in MongoDB or Elasticsearch filter syntax assuming the same grammar; LLM-generated filter dicts inventing operators; case mismatches from config-driven filter construction.
Related errors
- filters must contain at least one of: user_id, agent_id, run
- Invalid filter key: ${key}
- Filter value for ${key} must be str, int, float, or bool, go
- AND operator requires a list of conditions
- OR operator requires a non-empty list of conditions
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/634c77f89080f7d8.
Report an issue: GitHub.