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

  1. Use plain identifier keys: letters/digits/underscore, first char not a digit.
  2. Sanitize at the boundary: key = re.sub(r'[^A-Za-z0-9_]', '_', str(key)) or drop invalid keys with a warning.
  3. 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

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


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