mem0ai/mem0 · error · Error

Filter list for '${key}' contains an object, which may conta

Error message

Filter list for '${key}' contains an object, which may contain MongoDB query operators.

What it means

The MongoDB vector store whitelists filter values to scalars (and arrays of scalars) because object values in a MongoDB query filter are interpreted as query operators ($gt, $regex, $where...), which is an injection vector. If an array filter value contains an object element, the store refuses it before the query reaches MongoDB. This guards user-supplied filter input flowing into .find().

Source

Thrown at mem0-ts/src/oss/src/vector_stores/mongodb.ts:194

            `Atlas Search may not be available. keywordSearch() will not work.`,
        );
      }
    } catch (error) {
      console.error("Error initializing MongoDB:", error);
      throw error;
    }
  }

  private validateFilterValue(key: string, value: any): void {
    if (typeof value === "object" && value !== null) {
      if (Array.isArray(value)) {
        for (const item of value) {
          if (
            typeof item === "object" &&
            item !== null &&
            !Array.isArray(item)
          ) {
            throw new Error(
              `Filter list for '${key}' contains an object, which may contain MongoDB query operators.`,
            );
          }
        }
      } else {
        throw new Error(
          `Filter value for '${key}' must be a scalar (string, number, boolean), not an object. Objects may contain MongoDB query operators.`,
        );
      }
    }
  }

  async insert(
    vectors: number[][],
    ids: string[],
    payloads: Record<string, any>[],
  ): Promise<void> {
    await this.initialize();

View on GitHub (pinned to 001c235229)

Solutions

  1. Keep list values scalar-only: { tags: ['ai', 'memory'] }.
  2. Express exclusion via top-level filter design, not $ne objects inside lists.
  3. Validate/sanitize incoming filters with a schema (zod) that rejects object elements before they reach the store.

Example fix

// before
store.search(q, 5, { tags: ['ai', { $ne: 'beta' }] }); // throws

// after
store.search(q, 5, { tags: ['ai'] });
Defensive patterns

Strategy: validation

Validate before calling

for (const [k, v] of Object.entries(filters || {})) {
  if (Array.isArray(v) && v.some((it) => it !== null && typeof it === 'object')) {
    throw new Error(`Filter list '${k}' must contain scalars only`);
  }
}

Type guard

const isScalar = (v: unknown): boolean => ['string', 'number', 'boolean'].includes(typeof v);
const isSafeMongoValue = (v: unknown): boolean => isScalar(v) || (Array.isArray(v) && v.every(isScalar));

Try / catch

try { await store.search(q, 5, filters); }
catch (e) {
  if (e instanceof Error && e.message.includes('MongoDB query operators')) {
    // strip object elements from lists / reject the request as bad input
  } else throw e;
}

Prevention

When it happens

Trigger: Calling search() with { tags: ['a', { $ne: 'b' }] } or any array value containing an object; passing unvalidated user input (query params, JSON body fields) directly as SearchFilters; test fixtures that embed operator objects in list values.

Common situations: Public APIs exposing filter parameters to end users; converting Mongo queries wholesale into SearchFilters; LLM tool-calls that generate filter JSON with operator objects inside lists.

Related errors


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