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

  1. Use an array of sub-filters: { OR: [{ user_id: 'u1' }, { user_id: 'u2' }] }.
  2. For a single alternative, keep the plain field form { user_id: 'u1' } (no OR needed).
  3. 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

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


AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15). Data as JSON: /api/errors/973b526cf78e0b78. Report an issue: GitHub.