mem0ai/mem0 · error · Error
OR filter value must be a list of filter dicts, got ${typeof
Error message
OR filter value must be a list of filter dicts, got ${typeof value} What it means
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.
Source
Thrown at mem0-ts/src/oss/src/vector_stores/memory.ts:192
}
}
for (const [key, value] of Object.entries(normalized)) {
// Handle logical operators
if (key === "AND") {
if (!Array.isArray(value)) {
throw new Error(
`AND filter value must be a list of filter dicts, got ${typeof value}`,
);
}
// All conditions must match
const allMatch = value.every((sub: SearchFilters) =>
this.filterVector(vector, sub),
);
if (!allMatch) return false;
} else if (key === "OR") {
if (!Array.isArray(value)) {
throw new Error(
`OR filter value must be a list of filter dicts, got ${typeof value}`,
);
}
// At least one condition must match
const anyMatch = value.some((sub: SearchFilters) =>
this.filterVector(vector, sub),
);
if (!anyMatch) return false;
} else if (key === "NOT") {
if (!Array.isArray(value)) {
throw new Error(
`NOT filter value must be a list of filter dicts, got ${typeof value}`,
);
}
// None of the conditions should match
const noneMatch = value.every(
(sub: SearchFilters) => !this.filterVector(vector, sub),
);View on GitHub (pinned to 001c235229)
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().
Example fix
// before
store.search(q, 5, { OR: { user_id: 'u1' } }); // throws
// after
store.search(q, 5, { OR: [{ user_id: 'u1' }, { agent_id: 'a1' }] }); Defensive patterns
Strategy: validation
Validate before calling
if (filters.OR !== undefined && !Array.isArray(filters.OR)) {
filters = { ...filters, OR: [filters.OR] };
} Type guard
const isFilterList = (v: unknown): v is SearchFilters[] => Array.isArray(v) && v.every((e) => e && typeof e === 'object' && !Array.isArray(e));
Try / catch
try { results = await store.search(q, 5, filters); }
catch (e) {
if (e instanceof Error && e.message.startsWith('OR filter value')) throw new TypeError(`Bad OR filter: ${e.message}`);
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Converting a single-condition filter to an OR filter by just adding the OR key; JSON payloads from APIs where the array got unwrapped.
Related errors
- AND filter value must be a list of filter dicts, got ${typeo
- NOT filter value must be a list of filter dicts, got ${typeo
- AND filter value must be a list of filter dicts, got ${typeo
- OR filter value must be a list of filter dicts, got ${typeof
- NOT filter value must be a list of filter dicts, got ${typeo
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/973b526cf78e0b78.
Report an issue: GitHub.