{"record":{"id":"973b526cf78e0b78","repo":"mem0ai/mem0","slug":"or-filter-value-must-be-a-list-of-filter-dicts-go-973b52","errorCode":null,"errorMessage":"OR filter value must be a list of filter dicts, got ${typeof value}","messagePattern":"OR filter value must be a list of filter dicts, got (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mem0-ts/src/oss/src/vector_stores/memory.ts","lineNumber":192,"sourceCode":"      }\n    }\n\n    for (const [key, value] of Object.entries(normalized)) {\n      // Handle logical operators\n      if (key === \"AND\") {\n        if (!Array.isArray(value)) {\n          throw new Error(\n            `AND filter value must be a list of filter dicts, got ${typeof value}`,\n          );\n        }\n        // All conditions must match\n        const allMatch = value.every((sub: SearchFilters) =>\n          this.filterVector(vector, sub),\n        );\n        if (!allMatch) return false;\n      } else if (key === \"OR\") {\n        if (!Array.isArray(value)) {\n          throw new Error(\n            `OR filter value must be a list of filter dicts, got ${typeof value}`,\n          );\n        }\n        // At least one condition must match\n        const anyMatch = value.some((sub: SearchFilters) =>\n          this.filterVector(vector, sub),\n        );\n        if (!anyMatch) return false;\n      } else if (key === \"NOT\") {\n        if (!Array.isArray(value)) {\n          throw new Error(\n            `NOT filter value must be a list of filter dicts, got ${typeof value}`,\n          );\n        }\n        // None of the conditions should match\n        const noneMatch = value.every(\n          (sub: SearchFilters) => !this.filterVector(vector, sub),\n        );","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0-ts/src/oss/src/vector_stores/memory.ts#L174-L210","documentation":"Same guard as AND but for the 'OR' key in the SQLite MemoryVectorStore's filterVector: the value must be an array of filter dicts so .some() can evaluate each sub-condition. Any non-array (a single object, string, number) fails before evaluation, because the semantics of OR over a bare object are undefined.","triggerScenarios":"search(query, topK, { OR: { agent_id: 'a1' } }); or filters constructed as { OR: condition } where condition is an object rather than [condition]. Also triggered by user code that reuses one filter dict across AND/OR without wrapping.","commonSituations":"Converting a single-condition filter to an OR filter by just adding the OR key; JSON payloads from APIs where the array got unwrapped.","solutions":["Use an array of sub-filters: { OR: [{ user_id: 'u1' }, { user_id: 'u2' }] }.","For a single alternative, keep the plain field form { user_id: 'u1' } (no OR needed).","Validate filter shape at the boundary (API/CLI) with a schema check before passing to search()."],"exampleFix":"// before\nstore.search(q, 5, { OR: { user_id: 'u1' } }); // throws\n\n// after\nstore.search(q, 5, { OR: [{ user_id: 'u1' }, { agent_id: 'a1' }] });","handlingStrategy":"validation","validationCode":"if (filters.OR !== undefined && !Array.isArray(filters.OR)) {\n  filters = { ...filters, OR: [filters.OR] };\n}","typeGuard":"const isFilterList = (v: unknown): v is SearchFilters[] =>\n  Array.isArray(v) && v.every((e) => e && typeof e === 'object' && !Array.isArray(e));","tryCatchPattern":"try { results = await store.search(q, 5, filters); }\ncatch (e) {\n  if (e instanceof Error && e.message.startsWith('OR filter value')) throw new TypeError(`Bad OR filter: ${e.message}`);\n  throw e;\n}","preventionTips":["OR always takes an array, even for one alternative (or omit OR for a single condition).","Centralize filter construction in one builder function that enforces array shapes.","Add unit tests over filter shapes for each logical operator."],"tags":["filters","sqlite","vector-store","validation","typescript"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}