mem0ai/mem0 · error · ValueError
Invalid filter key: {key!r}
Error message
Invalid filter key: {key!r} What it means
ValueError from _validate_filter in elasticsearch.py: filter keys must be strings matching ^[a-zA-Z_][a-zA-Z0-9_]*$ before being embedded into the ES query DSL. Keys with dots, hyphens, spaces, leading digits, or non-str key types (int keys from JSON like {0: 'x'}) are rejected to keep the generated ES queries well-formed and injection-safe.
Source
Thrown at mem0/vector_stores/elasticsearch.py:30
from mem0.configs.vector_stores.elasticsearch import ElasticsearchConfig
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,View on GitHub (pinned to 001c235229)
Solutions
- Use plain identifier keys: letters/digits/underscore, first char not a digit.
- Sanitize at the boundary: key = re.sub(r'[^A-Za-z0-9_]', '_', str(key)) or drop invalid keys with a warning.
- Keep a whitelist of allowed filter keys per feature and validate input against it.
Example fix
# before
db.search(query, vectors, filters={"user-id": "alice"}) # ValueError
# after
db.search(query, vectors, filters={"user_id": "alice"}) Defensive patterns
Strategy: validation
Validate before calling
import re
_SAFE_KEY = re.compile(r"^[a-zA-Z_][a-zA-Z0-9_]*$")
def clean_es_filters(filters: dict) -> dict:
return {k: v for k, v in (filters or {}).items() if isinstance(k, str) and _SAFE_KEY.match(k)}
db.search(query, vectors, filters=clean_es_filters(filters)) Type guard
def has_safe_es_filter_keys(filters: dict) -> bool:
import re
return all(isinstance(k, str) and re.match(r"^[a-zA-Z_][a-zA-Z0-9_]*$", k) for k in (filters or {})) Prevention
- Store metadata under identifier-safe keys from the start.
- Do not translate ES DSL ('term'/'range' objects) into provider filters; use scalar equality only.
- Share one filter sanitizer across all vector store providers in your codebase.
When it happens
Trigger: Calling search/get on ElasticsearchDB with filters={'user-id': ...}, {'metadata.role': ...}, {123: 'v'}, or {'': 'x'}. Validation runs for each key/value pair before the ES query is built.
Common situations: Reusing filter dicts written for providers that allow dotted paths; keys sourced from arbitrary user/JSON payloads; numeric dict keys after JSON round-tripping.
Related errors
- Invalid filter key: ${JSON.stringify(key)}
- Filter value for ${JSON.stringify(key)} must be string, numb
- Invalid filter key: ${JSON.stringify(key)}
- Filter list for '${key}' contains an object, which may conta
- Filter value for '${key}' must be a scalar (string, number,
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/f4656e2e0e7e1f2e.
Report an issue: GitHub.