mem0ai/mem0 · error · ValueError
OR operator requires a non-empty list of conditions
Error message
OR operator requires a non-empty list of conditions
What it means
Raised inside _process_metadata_filters when the top-level 'OR' key is either not a list or is an empty list. OR conditions are passed through to the vector store as a '$or' structure, which requires at least one condition dict — an empty OR is meaningless (matches nothing) and a non-list OR cannot be enumerated, so both are rejected up front. Note OR is stricter than AND here: AND accepts an empty list, OR does not.
Source
Thrown at mem0/memory/main.py:1578
"""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))
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:View on GitHub (pinned to 001c235229)
Solutions
- Use a non-empty list of condition dicts: {'OR': [{'tag':'a'}, {'tag':'b'}]}.
- If the OR list would be empty, drop the OR key entirely (or return no results in your own logic).
- Guard builders: filters.setdefault('OR', []).append(cond) then delete the key if empty before calling search().
- Check isinstance(v, list) and len(v) > 0 for OR values pre-call.
Example fix
# before
branches = [c for c in candidates if c]
filters = {"user_id": "u1", "OR": branches} # branches == []
# after
filters = {"user_id": "u1"}
if branches:
filters["OR"] = branches Defensive patterns
Strategy: validation
Validate before calling
branches = [c for c in or_conditions if c]
filters = {"user_id": uid}
if branches:
filters["OR"] = branches Type guard
def is_valid_or(value) -> bool:
return isinstance(value, list) and len(value) > 0 Prevention
- OR must be a non-empty list (stricter than AND, which tolerates empty).
- Delete the OR key when the branch list is empty instead of passing [].
- Write a unit test for your filter builder covering the zero-branch case.
When it happens
Trigger: filters={'OR': {'a':{'eq':1},'b':{'eq':2}}} single dict; filters={'OR': []} empty list from a builder that found no branches; {'OR': ({'a':{'eq':1}},)} tuple; dynamically composing alternatives where none matched, e.g. ors = [c for c in candidates if c] yielding [].
Common situations: Rule engines building OR clauses from optional tags where no tags apply; LLM-generated filter syntax with OR as an object; refactors from $or Mongo syntax with wrong container type.
Related errors
- AND operator requires a list of conditions
- NOT 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/5bd5cb3473357128.
Report an issue: GitHub.