mem0ai/mem0 · error · ValueError

Filter value for {key!r} must be a scalar (str, int, float,

Error message

Filter value for {key!r} must be a scalar (str, int, float, bool), not a dict. Dicts may contain MongoDB query operators.

What it means

Security guard in the MongoDB vector store's filter validation: Mem0 turns filters into MongoDB match queries, so a dict value could smuggle query operators like $ne/$gt/$where and change the query semantics (NoSQL injection). Any non-scalar dict value for a filter key is rejected before the query is built.

Source

Thrown at mem0/vector_stores/mongodb.py:154

            ids (List[str], optional): List of IDs corresponding to vectors.
        """
        logger.info(f"Inserting {len(vectors)} vectors into collection '{self.collection_name}'.")

        data = []
        for vector, payload, _id in zip(vectors, payloads or [{}] * len(vectors), ids or [None] * len(vectors)):
            document = {"_id": _id, "embedding": vector, "payload": payload}
            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.

View on GitHub (pinned to 001c235229)

Solutions

  1. Flatten filters to scalar equality: use one key per value (str/int/float/bool)
  2. If you need range queries, execute them against MongoDB directly with a properly authorized client, not through Mem0's filter parameter
  3. Sanitize user-supplied filters at your API boundary before forwarding them to Mem0

Example fix

// before
filters = {"user_id": {"$ne": "alice"}}

// after
filters = {"user_id": "alice"}
Defensive patterns

Strategy: validation

Validate before calling

def safe_filters(filters: dict) -> dict:
    out = {}
    for k, v in (filters or {}).items():
        if isinstance(v, dict):
            raise ValueError(f"dict filter value for {k!r} not allowed")
        out[k] = v
    return out

filters = safe_filters(user_supplied_filters)
results = store.search(query, vector, top_k, filters=filters)

Type guard

def is_scalar_filter_value(v) -> bool:
    return isinstance(v, (str, int, float, bool))

Try / catch

try:
    store.search(q, vec, filters=filters)
except ValueError as e:
    if "MongoDB query operators" in str(e):
        filters = {k: v for k, v in filters.items() if not isinstance(v, dict)}
        store.search(q, vec, filters=filters)
    else:
        raise

Prevention

When it happens

Trigger: Passing filters={"user_id": {"$ne": "alice"}} or any nested dict as a filter value to search()/list operations on the MongoDB backend; building filters from unvalidated user input that happens to be a JSON object.

Common situations: Frontend-supplied JSON filter objects forwarded verbatim into memory search; developers used to MongoDB's native query syntax trying to express range conditions through Mem0's filter API.

Related errors


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