{"record":{"id":"5bd5cb3473357128","repo":"mem0ai/mem0","slug":"or-operator-requires-a-non-empty-list-of-condition-5bd5cb","errorCode":null,"errorMessage":"OR operator requires a non-empty list of conditions","messagePattern":"OR operator requires a non-empty list of conditions","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mem0/memory/main.py","lineNumber":1578,"sourceCode":"            \"\"\"Merge source into target, deep-merging nested operator dicts for the same key.\"\"\"\n            for key, value in source.items():\n                if key in target and isinstance(target[key], dict) and isinstance(value, dict):\n                    target[key].update(value)\n                else:\n                    target[key] = value\n\n        for key, value in metadata_filters.items():\n            if key == \"AND\":\n                # Logical AND: combine multiple conditions\n                if not isinstance(value, list):\n                    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:","sourceCodeStart":1560,"sourceCodeEnd":1596,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0/memory/main.py#L1560-L1596","documentation":"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.","triggerScenarios":"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 [].","commonSituations":"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.","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."],"exampleFix":"# before\nbranches = [c for c in candidates if c]\nfilters = {\"user_id\": \"u1\", \"OR\": branches}  # branches == []\n\n# after\nfilters = {\"user_id\": \"u1\"}\nif branches:\n    filters[\"OR\"] = branches","handlingStrategy":"validation","validationCode":"branches = [c for c in or_conditions if c]\nfilters = {\"user_id\": uid}\nif branches:\n    filters[\"OR\"] = branches","typeGuard":"def is_valid_or(value) -> bool:\n    return isinstance(value, list) and len(value) > 0","tryCatchPattern":null,"preventionTips":["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."],"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"}