{"record":{"id":"ef6d16d9d591ee96","repo":"mem0ai/mem0","slug":"filter-value-for-key-r-must-be-str-int-float","errorCode":null,"errorMessage":"Filter value for {key!r} must be str, int, float, or bool, got {type(value).__name__}","messagePattern":"Filter value for (.+?) must be str, int, float, or bool, got (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mem0/vector_stores/azure_ai_search.py","lineNumber":207,"sourceCode":"                raise Exception(f\"Insert failed for document {doc.get('id')}: {doc}\")\n        return response\n\n    def _sanitize_key(self, key: str) -> str:\n        return re.sub(r\"[^\\w]\", \"\", key)\n\n    def _build_filter_expression(self, filters):\n        filter_conditions = []\n        for key, value in filters.items():\n            safe_key = self._sanitize_key(key)\n            if isinstance(value, str):\n                safe_value = value.replace(\"'\", \"''\")\n                condition = f\"{safe_key} eq '{safe_value}'\"\n            elif isinstance(value, bool):\n                condition = f\"{safe_key} eq {str(value).lower()}\"\n            elif isinstance(value, (int, float)):\n                condition = f\"{safe_key} eq {value}\"\n            else:\n                raise ValueError(\n                    f\"Filter value for {key!r} must be str, int, float, or bool, \"\n                    f\"got {type(value).__name__}\"\n                )\n            filter_conditions.append(condition)\n        filter_expression = \" and \".join(filter_conditions)\n        return filter_expression\n\n    def search(self, query, vectors, top_k=5, filters=None):\n        \"\"\"\n        Search for similar vectors.\n\n        Args:\n            query (str): Query.\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. Defaults to None.\n\n        Returns:","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0/vector_stores/azure_ai_search.py#L189-L225","documentation":"Raised by AzureAISearch._build_filter_expression when a filters dict passed to search() contains a value whose type is not str, int, float, or bool. The builder interpolates values directly into an OData filter expression ('key eq value'), so it must be able to render the value as a literal; lists, dicts, None, and nested objects cannot be rendered and are rejected.","triggerScenarios":"Calling memory.search(query, user_id='u1', filters={'roles': ['admin']}) — list value; passing filters={'meta': None}; passing a nested dict filter={'user': {'id': 1}}; passing datetime objects.","commonSituations":"Forwarding arbitrary user metadata as filters; assuming filters support the same shapes as metadata stored at add() time; None values from optional request fields flowing into filters.","solutions":["Flatten list filters to a single scalar or use multiple scalar filters per key (Azure OData 'any/all' is not supported by this builder)","Drop None values from the filter dict before calling search","Serialize or omit dict/datetime values — store them in metadata at add() time, filter on scalar projections","Validate the filter dict shape before the call (see validationCode in defense)"],"exampleFix":"# before\nmemory.search(\"q\", user_id=\"u1\", filters={'roles': ['admin'], 'tenant': None})\n\n# after\nmemory.search(\"q\", user_id=\"u1\", filters={'role': 'admin'})","handlingStrategy":"type-guard","validationCode":"def sanitize_filters(filters: dict | None) -> dict:\n    if not filters:\n        return {}\n    bad = {k: type(v).__name__ for k, v in filters.items() if not isinstance(v, (str, int, float, bool))}\n    if bad:\n        raise ValueError(f'non-scalar filter values: {bad}')\n    return filters","typeGuard":"def filters_are_scalar(filters) -> bool:\n    return isinstance(filters, dict) and all(\n        isinstance(v, (str, int, float, bool)) and not isinstance(v, (list, dict, type(None)))\n        for v in filters.values()\n    )","tryCatchPattern":"try:\n    memory.search(q, user_id=uid, filters=filters)\nexcept ValueError as e:\n    if 'must be str, int, float, or bool' in str(e):\n        filters = sanitize_filters(filters)\n        results = memory.search(q, user_id=uid, filters=filters)\n    else:\n        raise","preventionTips":["Allow only scalar filter values in your API layer; strip None and reject lists","Store list-like metadata at add() time, filter on scalar projections","Add a unit test over your filter dict shapes before they reach mem0"],"tags":["azure","filters","search","type-validation"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}