{"record":{"id":"500c4b892a1194a2","repo":"mem0ai/mem0","slug":"filter-value-for-key-r-must-be-str-int-float-500c4b","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":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mem0/vector_stores/milvus.py","lineNumber":171,"sourceCode":"            filters (dict): filters [user_id, agent_id, run_id]\n\n        Returns:\n            str: formated filter.\n        \"\"\"\n        operands = []\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 value == \"*\":\n                # Wildcard - match any value (MilvusDB doesn't have direct wildcard, so we skip this filter)\n                continue\n            elif isinstance(value, str):\n                escaped = value.replace(\"\\\\\", \"\\\\\\\\\").replace('\"', '\\\\\"')\n                operands.append(f'(metadata[\"{key}\"] == \"{escaped}\")')\n            elif isinstance(value, (int, float, bool)):\n                operands.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\n        return \" and \".join(operands)\n\n    def _parse_output(self, data: list):\n        \"\"\"\n        Parse the output data.\n\n        Args:\n            data (Dict): Output data.\n\n        Returns:\n            List[OutputData]: Parsed output data.\n        \"\"\"\n        memory = []\n","sourceCodeStart":153,"sourceCodeEnd":189,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0/vector_stores/milvus.py#L153-L189","documentation":"Milvus._create_filter() only accepts filter values of str, int, float, bool, or the '*' wildcard; anything else (list, dict, None, tuple) cannot be rendered into the metadata[\"key\"] == <literal> expression and raises ValueError.","triggerScenarios":"Passing filters={'user_id': ['u1','u2']} (IN-style list), {'run_id': None}, or a nested dict as a value — mem0's Milvus filter builder has no operator syntax, only equality.","commonSituations":"Porting filters from Qdrant/other stores that support list membership (match any); forgetting that mem0 search filters are equality-only; '*' wildcard misuse as a dict value.","solutions":["Flatten list values into multiple searches (one per value) and merge results, since only equality is supported","Remove None/nested values from the filters dict before calling search","Use '*' only as a bare string value meaning match-any (it is skipped)"],"exampleFix":"# before\nfilters = {'user_id': ['u1', 'u2']}  # ValueError: must be str, int, float, or bool\nresults = m.search('q', filters=filters)\n\n# after\nresults = []\nfor uid in ['u1', 'u2']:\n    results.extend(m.search('q', filters={'user_id': uid}))","handlingStrategy":"validation","validationCode":"def coerce_filters(filters):\n    out = {}\n    for k, v in (filters or {}).items():\n        if v is None or isinstance(v, (list, tuple, dict, set)):\n            continue  # unsupported value type: skip or explode lists upstream\n        out[k] = v\n    return out","typeGuard":"def is_supported_filter_value(v) -> bool:\n    return isinstance(v, (str, int, float, bool)) and not isinstance(v, (list, dict))","tryCatchPattern":"try:\n    m.search('query', filters=filters)\nexcept ValueError as e:\n    if 'must be str, int, float, or bool' in str(e):\n        filters = coerce_filters(filters)\n        results = m.search('query', filters=filters)\n    else:\n        raise","preventionTips":["Remember mem0 Milvus filters are equality-only: no lists, None, or nested dicts","Flatten list values into repeated searches if you need OR semantics","Validate the filters dict shape in one shared helper before every search call"],"tags":["milvus","filters","type-validation","search"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}