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
Raised by `_validate_filter` when a filter value's type is not one of str, int, float, bool. Because the filter is serialized into a query string (same injection concern as the key check), composite types — dict, list, None — are rejected outright; there is no JSON-encoding escape hatch. Note bool passes because it subclasses int.
Source
Thrown at mem0/vector_stores/upstash_vector.py:24
from mem0.vector_stores.base import VectorStoreBase
try:
from upstash_vector import Index
except ImportError:
raise ImportError("The 'upstash_vector' library is required. Please install it using 'pip install upstash_vector'.")
logger = logging.getLogger(__name__)
_SAFE_FILTER_KEY = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*\Z")
def _validate_filter(key: str, value: Any) -> None:
if not isinstance(key, str) or not _SAFE_FILTER_KEY.fullmatch(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__}"
)
if isinstance(value, str) and ('"' in value or "\\" in value):
raise ValueError(
f"Filter value for {key!r} contains prohibited characters "
f"(double quote or backslash): {value!r}"
)
class OutputData(BaseModel):
id: Optional[str] # memory id
score: Optional[float] # is None for `get` method
payload: Optional[Dict] # metadata
class UpstashVector(VectorStoreBase):
def __init__(View on GitHub (pinned to 001c235229)
Solutions
- Replace list values with multiple searches or precomputed membership: store a scalar field (e.g. set membership flattened into separate boolean/scalar keys) or query per value and merge results.
- Drop None-valued keys before filtering: `{k: v for k, v in filters.items() if v is not None}`.
- Flatten nested dicts into dotless top-level scalar fields at insert time.
Example fix
# before
filters = {"user_id": ["u1", "u2"], "run_id": None}
# after
filters = {"user_id": "u1"} # one value per query; loop and merge for multiple
results = [r for uid in ("u1", "u2") for r in memory.search("q", filters={"user_id": uid})] Defensive patterns
Strategy: type-guard
Validate before calling
def validate_filter_values(filters: dict) -> None:
for k, v in filters.items():
if not isinstance(v, (str, int, float, bool)):
raise ValueError(f"Filter value for {k!r} must be scalar (str/int/float/bool), got {type(v).__name__}") Type guard
def is_scalar_filter_value(v) -> bool:
return isinstance(v, (str, int, float, bool)) and v is not None Try / catch
try:
results = memory.search("q", filters=filters)
except ValueError as e:
if "must be str, int, float, or bool" in str(e):
raise BadRequest(f"Scalar filter values only: {filters}") from e
raise Prevention
- Never assume list values mean IN on Upstash — they are rejected; loop over values instead.
- Strip None-valued keys before filtering.
- Flatten nested metadata into scalar fields at insert time.
When it happens
Trigger: Filters like `{"user_id": ["u1", "u2"]}` (list for an IN), `{"meta": {"a": 1}}` (nested dict), or `{"flag": None}` — all unsupported value shapes for Upstash.
Common situations: Assuming list values give OR semantics like other mem0 backends (Qdrant treats a list as match-any); passing optional fields that default to None; reusing filter dicts written for a different vector store backend.
Related errors
- Invalid filter key: {key!r}
- Filter value for {key!r} contains prohibited characters (dou
- Filter value for ${key} must be str, int, float, or bool, go
- AND filter value must be a list of filter dicts, got ${typeo
- OR filter value must be a list of filter dicts, got ${typeof
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/06a6c609df7d0e1d.
Report an issue: GitHub.