mem0ai/mem0 · error · Error
AND filter value must be a list of filter dicts, got ${typeo
Error message
AND filter value must be a list of filter dicts, got ${typeof value} What it means
filterVector() throws when a filters object contains an AND key whose value is not an array. After key normalization ($and maps to AND), the compound AND filter is expected to be a list of sub-filter dicts applied with .every(); a non-array value cannot be evaluated, so the provider fails fast rather than silently skipping the filter.
Source
Thrown at mem0-ts/src/oss/src/vector_stores/databricks.ts:1583
}
const keyMap: Record<string, string> = {
$and: "AND",
$or: "OR",
$not: "NOT",
};
const normalized: Record<string, any> = {};
for (const [key, value] of Object.entries(filters)) {
const normalizedKey = keyMap[key] || key;
if (!(normalizedKey in normalized)) {
normalized[normalizedKey] = value;
}
}
for (const [key, value] of Object.entries(normalized)) {
if (key === "AND") {
if (!Array.isArray(value)) {
throw new Error(
`AND filter value must be a list of filter dicts, got ${typeof value}`,
);
}
if (
!value.every((entry: SearchFilters) =>
this.filterVector(vector, entry),
)
) {
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}`,
);
}
if (
!value.some((entry: SearchFilters) =>View on GitHub (pinned to 001c235229)
Solutions
- Wrap AND branches in an array: { AND: [ {...}, {...} ] }.
- When building filters programmatically, always push sub-filters into an array even for a single condition.
- If the filter came from JSON config, validate its shape before passing it to search().
Example fix
// before
store.search(query, 5, { $and: { user_id: 'u1', run_id: 'r2' } });
// after
store.search(query, 5, { $and: [{ user_id: 'u1' }, { run_id: 'r2' }] }); Defensive patterns
Strategy: type-guard
Validate before calling
const isCompoundList = (f: Record<string, unknown>) =>
(['AND', 'OR', 'NOT'] as const).every((k) => !(k in f) || Array.isArray(f[k]));
if (!isCompoundList(filters)) throw new Error('AND/OR/NOT branches must be arrays'); Type guard
type Branch = Record<string, string | number | boolean>;
interface SafeFilters {
AND?: Branch[];
OR?: Branch[];
NOT?: Branch[];
[k: string]: unknown;
}
const isSafeFilters = (f: unknown): f is SafeFilters =>
typeof f === 'object' && f !== null &&
Object.entries(f).every(([k, v]) =>
['AND', 'OR', 'NOT'].includes(k) ? Array.isArray(v) : true,
); Try / catch
try {
await store.search(q, k, filters);
} catch (e) {
if (e instanceof Error && e.message.includes('AND filter value must be a list')) {
// rewrite { AND: {...} } to { AND: [{...}] } and retry
}
throw e;
} Prevention
- Always author compound branches as arrays of single-key objects, even with one condition.
- Centralize filter construction in one typed helper.
- Add unit tests asserting the array shape for AND/OR/NOT.
When it happens
Trigger: Calling search()/list() with filters like { AND: { user_id: 'u1' } } (object instead of array), or { $and: 'user_id' } (string). Correct shape is { AND: [{ user_id: 'u1' }, { run_id: 'r1' }] }.
Common situations: Translating Qdrant-style or Python-dict filter syntax into the TS SDK and forgetting the list wrapper around $and branches; building filters dynamically where an empty/single condition collapses to a bare object.
Related errors
- OR filter value must be a list of filter dicts, got ${typeof
- 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/0c5745f5e9e496c1.
Report an issue: GitHub.