mem0ai/mem0 · error · ValueError
NOT operator requires a non-empty list of conditions
Error message
NOT operator requires a non-empty list of conditions
What it means
Raised inside _process_metadata_filters when the top-level 'NOT' key is not a list or is an empty list — the exact same contract as OR. NOT conditions are translated to a '$not' list passed through to the vector store, so at least one condition dict in a list is required. An empty NOT would be a no-op and is rejected rather than silently ignored, which helps catch broken filter construction.
Source
Thrown at mem0/memory/main.py:1589
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))
elif key == "OR":
# Logical OR: Pass through to vector store for implementation-specific handling
if not isinstance(value, list) or not value:
raise ValueError("OR operator requires a non-empty list of conditions")
# Store OR conditions in a way that vector stores can interpret
processed_filters["$or"] = []
for condition in value:
or_condition = {}
for sub_key, sub_value in condition.items():
merge_filters(or_condition, process_condition(sub_key, sub_value))
processed_filters["$or"].append(or_condition)
elif key == "NOT":
# Logical NOT: Pass through to vector store for implementation-specific handling
if not isinstance(value, list) or not value:
raise ValueError("NOT operator requires a non-empty list of conditions")
processed_filters["$not"] = []
for condition in value:
not_condition = {}
for sub_key, sub_value in condition.items():
merge_filters(not_condition, process_condition(sub_key, sub_value))
processed_filters["$not"].append(not_condition)
else:
merge_filters(processed_filters, process_condition(key, value))
return processed_filters
def _has_advanced_operators(self, filters: Dict[str, Any]) -> bool:
"""
Check if filters contain advanced operators that need special processing.
Args:
filters: Dictionary of filters to check
View on GitHub (pinned to 001c235229)
Solutions
- Use a non-empty list: {'NOT': [{'tag':'spam'}]}.
- If nothing should be excluded, remove the NOT key instead of passing an empty list.
- Build exclusions conditionally: if exclusions: filters['NOT'] = exclusions.
- Validate logical keys uniformly: value must be a list, and non-empty for OR/NOT.
Example fix
# before
filters = {"user_id": "u1", "NOT": excluded_tags or []}
# after
filters = {"user_id": "u1"}
if excluded_tags:
filters["NOT"] = [{"tag": t} for t in excluded_tags] Defensive patterns
Strategy: validation
Validate before calling
if excluded:
filters["NOT"] = [{k: {"eq": v}} for k, v in excluded.items()]
# never set filters["NOT"] = [] Type guard
def is_valid_not(value) -> bool:
return isinstance(value, list) and len(value) > 0 Prevention
- NOT must be a non-empty list of condition dicts, same contract as OR.
- Drop the NOT key when nothing is excluded — empty NOT is rejected, not treated as no-op.
- Validate logical keys uniformly (list for AND, non-empty list for OR/NOT) in one helper.
When it happens
Trigger: filters={'NOT': {'tag':'spam'}} single dict instead of list; {'NOT': []} from an exclusion list that ended up empty; tuple values from functional builders; copy-pasting Mongo {'$not': {...}} shape adapted incorrectly.
Common situations: Exclusion lists (blocked tags, muted users) that are empty by configuration; config-driven filter generation; LLM-authored filters with object-style NOT.
Related errors
- AND operator requires a list of conditions
- OR operator requires a non-empty list of conditions
- 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
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/9a631ea2933f88fb.
Report an issue: GitHub.