mem0ai/mem0 · error · ValueError

Filter list for {key!r} contains a dict, which may contain M

Error message

Filter list for {key!r} contains a dict, which may contain MongoDB query operators.

What it means

Companion guard to the scalar check: it rejects filter values that are lists containing dict items, because those dicts could carry MongoDB query operators. Plain scalar lists are allowed; only list elements that are dicts are blocked.

Source

Thrown at mem0/vector_stores/mongodb.py:161

            data.append(document)
        try:
            self.collection.insert_many(data)
            logger.info(f"Inserted {len(data)} documents into '{self.collection_name}'.")
        except PyMongoError as e:
            logger.error(f"Error inserting data: {e}")

    @staticmethod
    def _validate_filter_value(key: str, value: Any) -> None:
        """Reject values that could inject MongoDB query operators (e.g. $ne, $gt)."""
        if isinstance(value, dict):
            raise ValueError(
                f"Filter value for {key!r} must be a scalar (str, int, float, bool), "
                f"not a dict. Dicts may contain MongoDB query operators."
            )
        if isinstance(value, list):
            for item in value:
                if isinstance(item, dict):
                    raise ValueError(
                        f"Filter list for {key!r} contains a dict, "
                        f"which may contain MongoDB query operators."
                    )

    def search(self, query: str, vectors: List[float], top_k=5, filters: Optional[Dict] = None) -> List[OutputData]:
        """
        Search for similar vectors using the vector search index.

        Args:
            query (str): Query string
            vectors (List[float]): Query vector.
            top_k (int, optional): Number of results to return. Defaults to 5.
            filters (Dict, optional): Filters to apply to the search.

        Returns:
            List[OutputData]: Search results.
        """

View on GitHub (pinned to 001c235229)

Solutions

  1. Map list filters to plain scalar lists: ["a", "b", 1] is fine, [{...}] is not
  2. Extract the scalar field you actually want to match on before building the filter
  3. Validate filter shape at your service boundary with a schema (e.g. Pydantic) that forbids dict elements

Example fix

// before
filters = {"app_id": [{"$regex": "^prod"}, "dev"]}

// after
filters = {"app_id": ["prod-1", "dev-2"]}
Defensive patterns

Strategy: validation

Validate before calling

def flatten_list_filters(filters: dict) -> dict:
    for k, v in (filters or {}).items():
        if isinstance(v, list) and any(isinstance(i, dict) for i in v):
            raise ValueError(f"list filter {k!r} contains objects")
    return filters

Type guard

def is_safe_filter_list(v) -> bool:
    return not isinstance(v, list) or all(isinstance(i, (str, int, float, bool)) for i in v)

Try / catch

try:
    store.search(q, vec, filters=filters)
except ValueError:
    filters = {k: [i for i in v if not isinstance(i, dict)] if isinstance(v, list) else v
               for k, v in filters.items()}
    store.search(q, vec, filters=filters)

Prevention

When it happens

Trigger: Passing filters={"app_id": [{"$gt": 1}, "x"]} to the MongoDB backend's search; unmarshalled JSON arrays-of-objects forwarded as filter values.

Common situations: API clients sending structured arrays in filters; a serialization bug where a list of records accidentally ends up as an $in-style filter value.

Related errors


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