{"record":{"id":"8ca0782a4e19cda0","repo":"mem0ai/mem0","slug":"or-operator-requires-a-non-empty-list-of-condition","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":null,"httpStatus":null,"severity":"error","filePath":"mem0-ts/src/oss/src/memory/index.ts","lineNumber":2161,"sourceCode":"      }\n      return result;\n    };\n\n    for (const [key, value] of Object.entries(metadataFilters)) {\n      if (key === \"AND\") {\n        // Logical AND: combine multiple conditions\n        if (!Array.isArray(value)) {\n          throw new Error(\"AND operator requires a list of conditions\");\n        }\n        for (const condition of value) {\n          for (const [subKey, subValue] of Object.entries(condition)) {\n            Object.assign(processedFilters, processCondition(subKey, subValue));\n          }\n        }\n      } else if (key === \"OR\") {\n        // Logical OR: Pass through to vector store for implementation-specific handling\n        if (!Array.isArray(value) || value.length === 0) {\n          throw new Error(\n            \"OR operator requires a non-empty list of conditions\",\n          );\n        }\n        processedFilters[\"$or\"] = [];\n        for (const condition of value) {\n          const orCondition: Record<string, any> = {};\n          for (const [subKey, subValue] of Object.entries(\n            condition as Record<string, any>,\n          )) {\n            Object.assign(orCondition, processCondition(subKey, subValue));\n          }\n          processedFilters[\"$or\"].push(orCondition);\n        }\n      } else if (key === \"NOT\") {\n        // Logical NOT: Pass through to vector store for implementation-specific handling\n        if (!Array.isArray(value) || value.length === 0) {\n          throw new Error(\n            \"NOT operator requires a non-empty list of conditions\",","sourceCodeStart":2143,"sourceCodeEnd":2179,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0-ts/src/oss/src/memory/index.ts#L2143-L2179","documentation":"Thrown during metadata filter preprocessing when the OR key's value is not an array or is an empty array. OR conditions are passed through to the vector store as a $or list, and an empty or malformed list would produce an invalid query. Unlike AND, the emptiness check is explicit.","triggerScenarios":"Writing OR: {} (object), OR: [] (empty list), or OR: undefined after dynamic filter construction drops the conditions array.","commonSituations":"Building OR from a list of user-chosen tags that turns out empty; copying the AND object shape for OR; programmatically collapsing a one-element OR incorrectly.","solutions":["Provide a non-empty array: OR: [{ tag: { equals: 'a' } }, { tag: { equals: 'b' } }]","If the dynamic OR list can be empty, fall back to omitting the OR key entirely","For a single OR condition, still use the array form"],"exampleFix":"// before\nfilters: { user_id: 'u1', OR: [] }\n\n// after\nconst tagConds = tags.map(t => ({ tag: { equals: t } }));\nconst filters = { user_id: 'u1', ...(tagConds.length ? { OR: tagConds } : {}) };","handlingStrategy":"type-guard","validationCode":"function orKey(conds: unknown[]) { return Array.isArray(conds) && conds.length ? { OR: conds } : {}; }","typeGuard":"const isNonEmptyConditionArray = (v: unknown): v is object[] =>\n  Array.isArray(v) && v.length > 0 && v.every((c) => typeof c === 'object' && c !== null);","tryCatchPattern":null,"preventionTips":["Only add OR to filters when the condition array is non-empty","Treat empty dynamic OR lists as 'no filter' rather than an empty array"],"tags":["validation","oss","filters","metadata"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}