{"record":{"id":"9a631ea2933f88fb","repo":"mem0ai/mem0","slug":"not-operator-requires-a-non-empty-list-of-conditio-9a631e","errorCode":null,"errorMessage":"NOT operator requires a non-empty list of conditions","messagePattern":"NOT operator requires a non-empty list of conditions","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mem0/memory/main.py","lineNumber":1589,"sourceCode":"                    raise ValueError(\"AND operator requires a list of conditions\")\n                for condition in value:\n                    for sub_key, sub_value in condition.items():\n                        merge_filters(processed_filters, process_condition(sub_key, sub_value))\n            elif key == \"OR\":\n                # Logical OR: Pass through to vector store for implementation-specific handling\n                if not isinstance(value, list) or not value:\n                    raise ValueError(\"OR operator requires a non-empty list of conditions\")\n                # Store OR conditions in a way that vector stores can interpret\n                processed_filters[\"$or\"] = []\n                for condition in value:\n                    or_condition = {}\n                    for sub_key, sub_value in condition.items():\n                        merge_filters(or_condition, process_condition(sub_key, sub_value))\n                    processed_filters[\"$or\"].append(or_condition)\n            elif key == \"NOT\":\n                # Logical NOT: Pass through to vector store for implementation-specific handling\n                if not isinstance(value, list) or not value:\n                    raise ValueError(\"NOT operator requires a non-empty list of conditions\")\n                processed_filters[\"$not\"] = []\n                for condition in value:\n                    not_condition = {}\n                    for sub_key, sub_value in condition.items():\n                        merge_filters(not_condition, process_condition(sub_key, sub_value))\n                    processed_filters[\"$not\"].append(not_condition)\n            else:\n                merge_filters(processed_filters, process_condition(key, value))\n\n        return processed_filters\n\n    def _has_advanced_operators(self, filters: Dict[str, Any]) -> bool:\n        \"\"\"\n        Check if filters contain advanced operators that need special processing.\n        \n        Args:\n            filters: Dictionary of filters to check\n            ","sourceCodeStart":1571,"sourceCodeEnd":1607,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0/memory/main.py#L1571-L1607","documentation":"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.","triggerScenarios":"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.","commonSituations":"Exclusion lists (blocked tags, muted users) that are empty by configuration; config-driven filter generation; LLM-authored filters with object-style NOT.","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."],"exampleFix":"# before\nfilters = {\"user_id\": \"u1\", \"NOT\": excluded_tags or []}\n\n# after\nfilters = {\"user_id\": \"u1\"}\nif excluded_tags:\n    filters[\"NOT\"] = [{\"tag\": t} for t in excluded_tags]","handlingStrategy":"validation","validationCode":"if excluded:\n    filters[\"NOT\"] = [{k: {\"eq\": v}} for k, v in excluded.items()]\n# never set filters[\"NOT\"] = []","typeGuard":"def is_valid_not(value) -> bool:\n    return isinstance(value, list) and len(value) > 0","tryCatchPattern":null,"preventionTips":["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."],"tags":["validation","filters","logical-operators","search"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}