{"record":{"id":"f3c7c890c5d6b388","repo":"mem0ai/mem0","slug":"filter-value-for-key-r-must-be-str-int-float-f3c7c8","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/baidu.py","lineNumber":425,"sourceCode":"        Create filter expression for queries.\n\n        Args:\n            filters (dict): Filter conditions.\n\n        Returns:\n            str: Filter expression.\n        \"\"\"\n        conditions = []\n        for key, value in filters.items():\n            if not self._SAFE_FILTER_KEY.match(key):\n                raise ValueError(f\"Invalid filter key: {key!r}\")\n            if isinstance(value, str):\n                escaped = value.replace(\"\\\\\", \"\\\\\\\\\").replace('\"', '\\\\\"')\n                conditions.append(f'metadata[\"{key}\"] = \"{escaped}\"')\n            elif isinstance(value, (int, float, bool)):\n                conditions.append(f'metadata[\"{key}\"] = {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        return \" AND \".join(conditions)\n","sourceCodeStart":407,"sourceCodeEnd":430,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0/vector_stores/baidu.py#L407-L430","documentation":"BaiduDB._create_filter raises ValueError when a filter VALUE is not str, int, float, or bool. Values are string-formatted into the query expression, so unsupported types (None, list, dict, datetime) cannot be rendered safely and are rejected instead of coerced. Note bool passes because it subclasses int, but NoneType does not.","triggerScenarios":"Calling search with filters={'role': None}, filters={'tags': ['a','b']}, filters={'when': {'$gt': 5}}, or any dict/list/None value. The type name is included in the message (got dict, got NoneType, got list).","commonSituations":"Optional metadata fields that are None when unset; passing Mongo/Qdrant-style filter DSLs ({'$gt': ...}, nested dicts) to a provider that only supports equality; serializing datetimes as datetime objects instead of ISO strings.","solutions":["Flatten filters to scalar equality comparisons: use str/int/float/bool values only.","Convert None to a sentinel string (e.g. 'null') or omit the key, and stringify datetimes: value.isoformat().","For range/in-list semantics, pre-compute on the application side or store a derived boolean/field, since BaiduDB only supports equality."],"exampleFix":"# before\ndb.search(query, vectors, filters={\"since\": {\"$gt\": \"2024-01-01\"}})  # ValueError: got dict\n\n# after\ndb.search(query, vectors, filters={\"since_gt_2024_01_01\": True})","handlingStrategy":"type-guard","validationCode":"def to_scalar_filters(filters: dict) -> dict:\n    out = {}\n    for k, v in (filters or {}).items():\n        if v is None:\n            continue\n        if isinstance(v, (str, int, float, bool)):\n            out[k] = v.isoformat() if hasattr(v, \"isoformat\") else v\n        else:\n            raise ValueError(f\"filter {k!r} must be scalar, got {type(v).__name__}\")\n    return out\n\ndb.search(query, vectors, filters=to_scalar_filters(filters))","typeGuard":"def is_scalar_filter_value(v) -> bool:\n    return isinstance(v, (str, int, float, bool))","tryCatchPattern":null,"preventionTips":["Define filters as TypedDict fields with scalar types so mypy catches dict/list values.","Convert datetimes to ISO strings and drop Nones before calling search.","Remember this backend is equality-only: express ranges as precomputed fields."],"tags":["baidu","filters","validation","type-error"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}