{"record":{"id":"3661ade241c83a49","repo":"mem0ai/mem0","slug":"filter-list-for-key-r-contains-a-dict-which-may","errorCode":null,"errorMessage":"Filter list for {key!r} contains a dict, which may contain MongoDB query operators.","messagePattern":"Filter list for (.+?) contains a dict, which may contain MongoDB query operators\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mem0/vector_stores/mongodb.py","lineNumber":161,"sourceCode":"            data.append(document)\n        try:\n            self.collection.insert_many(data)\n            logger.info(f\"Inserted {len(data)} documents into '{self.collection_name}'.\")\n        except PyMongoError as e:\n            logger.error(f\"Error inserting data: {e}\")\n\n    @staticmethod\n    def _validate_filter_value(key: str, value: Any) -> None:\n        \"\"\"Reject values that could inject MongoDB query operators (e.g. $ne, $gt).\"\"\"\n        if isinstance(value, dict):\n            raise ValueError(\n                f\"Filter value for {key!r} must be a scalar (str, int, float, bool), \"\n                f\"not a dict. Dicts may contain MongoDB query operators.\"\n            )\n        if isinstance(value, list):\n            for item in value:\n                if isinstance(item, dict):\n                    raise ValueError(\n                        f\"Filter list for {key!r} contains a dict, \"\n                        f\"which may contain MongoDB query operators.\"\n                    )\n\n    def search(self, query: str, vectors: List[float], top_k=5, filters: Optional[Dict] = None) -> List[OutputData]:\n        \"\"\"\n        Search for similar vectors using the vector search index.\n\n        Args:\n            query (str): Query string\n            vectors (List[float]): Query vector.\n            top_k (int, optional): Number of results to return. Defaults to 5.\n            filters (Dict, optional): Filters to apply to the search.\n\n        Returns:\n            List[OutputData]: Search results.\n        \"\"\"\n","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0/vector_stores/mongodb.py#L143-L179","documentation":"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.","triggerScenarios":"Passing filters={\"app_id\": [{\"$gt\": 1}, \"x\"]} to the MongoDB backend's search; unmarshalled JSON arrays-of-objects forwarded as filter values.","commonSituations":"API clients sending structured arrays in filters; a serialization bug where a list of records accidentally ends up as an $in-style filter value.","solutions":["Map list filters to plain scalar lists: [\"a\", \"b\", 1] is fine, [{...}] is not","Extract the scalar field you actually want to match on before building the filter","Validate filter shape at your service boundary with a schema (e.g. Pydantic) that forbids dict elements"],"exampleFix":"// before\nfilters = {\"app_id\": [{\"$regex\": \"^prod\"}, \"dev\"]}\n\n// after\nfilters = {\"app_id\": [\"prod-1\", \"dev-2\"]}","handlingStrategy":"validation","validationCode":"def flatten_list_filters(filters: dict) -> dict:\n    for k, v in (filters or {}).items():\n        if isinstance(v, list) and any(isinstance(i, dict) for i in v):\n            raise ValueError(f\"list filter {k!r} contains objects\")\n    return filters","typeGuard":"def is_safe_filter_list(v) -> bool:\n    return not isinstance(v, list) or all(isinstance(i, (str, int, float, bool)) for i in v)","tryCatchPattern":"try:\n    store.search(q, vec, filters=filters)\nexcept ValueError:\n    filters = {k: [i for i in v if not isinstance(i, dict)] if isinstance(v, list) else v\n               for k, v in filters.items()}\n    store.search(q, vec, filters=filters)","preventionTips":["Map structured values to scalar lists before filtering","Validate filter arrays at the API boundary","Log rejected filter shapes once so upstream senders can fix their payloads"],"tags":["mongodb","nosql-injection","security","filters","validation"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}