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

  1. Use a non-empty list: {'NOT': [{'tag':'spam'}]}.
  2. If nothing should be excluded, remove the NOT key instead of passing an empty list.
  3. Build exclusions conditionally: if exclusions: filters['NOT'] = exclusions.
  4. 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

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


AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15). Data as JSON: /api/errors/9a631ea2933f88fb. Report an issue: GitHub.