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

  1. 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.
  2. Drop None-valued keys before filtering: `{k: v for k, v in filters.items() if v is not None}`.
  3. 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

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


AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15). Data as JSON: /api/errors/06a6c609df7d0e1d. Report an issue: GitHub.