mem0ai/mem0 · error · ValueError
Filter value for {key!r} must be str, int, float, or bool, g
Error message
Filter value for {key!r} must be str, int, float, or bool, got {type(value).__name__} What it means
ValueError from _validate_filter in elasticsearch.py when a filter value is not str, int, float, or bool. The value is placed directly into the ES term query, so unrenderable types (None, list, dict, datetime) are rejected up front rather than producing a malformed query or a confusing server error.
Source
Thrown at mem0/vector_stores/elasticsearch.py:32
from mem0.vector_stores.base import VectorStoreBase
logger = logging.getLogger(__name__)
class OutputData(BaseModel):
id: str
score: float
payload: Dict
_SAFE_FILTER_KEY = re.compile(r"^[a-zA-Z_][a-zA-Z0-9_]*$")
def _validate_filter(key: str, value: Any) -> None:
if not isinstance(key, str) or not _SAFE_FILTER_KEY.match(key):
raise ValueError(f"Invalid filter key: {key!r}")
if not isinstance(value, (str, int, float, bool)):
raise ValueError(
f"Filter value for {key!r} must be str, int, float, or bool, "
f"got {type(value).__name__}"
)
class ElasticsearchDB(VectorStoreBase):
def __init__(self, **kwargs):
config = ElasticsearchConfig(**kwargs)
# Initialize Elasticsearch client
if config.cloud_id:
self.client = Elasticsearch(
cloud_id=config.cloud_id,
api_key=config.api_key,
verify_certs=config.verify_certs,
ca_certs=config.ca_certs,
headers= config.headers or {},
)View on GitHub (pinned to 001c235229)
Solutions
- Omit keys whose value is None: {k: v for k, v in filters.items() if v is not None}.
- Convert datetimes to strings and flatten lists to a single scalar or repeated equality terms as supported.
- For range queries, pre-compute a boolean/bucketed field because only equality filtering is supported here.
Example fix
# before
db.search(query, vectors, filters={"since": {"gte": "2024-01-01"}}) # ValueError: got dict
# after
filters = {"user_id": "alice"} # scalars only; convert/remove the rest
db.search(query, vectors, filters=filters) Defensive patterns
Strategy: type-guard
Validate before calling
def scalarize_filters(filters: dict) -> dict:
out = {}
for k, v in (filters or {}).items():
if v is None:
continue
if hasattr(v, "isoformat"):
v = v.isoformat()
if not isinstance(v, (str, int, float, bool)):
raise ValueError(f"filter {k!r} must be scalar, got {type(v).__name__}")
out[k] = v
return out
db.search(query, vectors, filters=scalarize_filters(filters)) Type guard
def is_scalar_filter_value(v) -> bool:
return isinstance(v, (str, int, float, bool)) and not hasattr(v, "isoformat") Prevention
- Type filter dicts as Mapping[str, str|int|float|bool] in your codebase.
- Convert datetimes to ISO strings and drop None values before calling search.
- Reserve ranges/lists for application-side filtering; this path supports equality only.
When it happens
Trigger: search/get with filters={'role': None}, {'tags': ['a']}, {'ts': datetime.now()}, or nested operator dicts ({'gte': 1}). bool is accepted (subclass of int); None is not.
Common situations: Optional filters left as None instead of omitted; passing range/query DSL fragments from other libraries; datetime objects not converted to ISO strings.
Related errors
- Filter value for ${key} must be str, int, float, or bool, go
- Invalid filter key: ${JSON.stringify(key)}
- Filter value for ${JSON.stringify(key)} must be string, numb
- Filter value for {key!r} must be str, int, float, or bool, g
- Invalid filter key: {key!r}
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/1ee0505b9b73dd3e.
Report an issue: GitHub.