mem0ai/mem0 · error · ValueError
Invalid {label} '{name}': only letters, digits, and undersco
Error message
Invalid {label} '{name}': only letters, digits, and underscores are allowed, must start with a letter or underscore, and be at most 128 characters. What it means
ValueError from the module-level _validate_identifier helper in cassandra.py, used for keyspace and table names before any CQL is executed. It enforces ^[a-zA-Z_][a-zA-Z0-9_]{0,127}$: must start with a letter or underscore, only letters/digits/underscores after that, and at most 128 characters. This blocks CQL injection and invalid identifiers before they reach the cluster.
Source
Thrown at mem0/vector_stores/cassandra.py:28
try:
from cassandra.auth import PlainTextAuthProvider
from cassandra.cluster import Cluster
except ImportError:
raise ImportError(
"Apache Cassandra vector store requires cassandra-driver. "
"Please install it using 'pip install cassandra-driver'"
)
from mem0.vector_stores.base import VectorStoreBase
logger = logging.getLogger(__name__)
_SAFE_IDENTIFIER_RE = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]{0,127}$')
def _validate_identifier(name: str, label: str = "identifier") -> str:
if not _SAFE_IDENTIFIER_RE.match(name):
raise ValueError(
f"Invalid {label} '{name}': only letters, digits, and underscores are allowed, "
"must start with a letter or underscore, and be at most 128 characters."
)
return name
class OutputData(BaseModel):
id: Optional[str]
score: Optional[float]
payload: Optional[dict]
class CassandraDB(VectorStoreBase):
def __init__(
self,
contact_points: List[str],
port: int = 9042,
username: Optional[str] = None,View on GitHub (pinned to 001c235229)
Solutions
- Rename the keyspace/collection to match the identifier rule: letters, digits, underscores only, starting with a letter or underscore, <=128 chars.
- If the name is dynamic, sanitize it: re.sub(r'[^A-Za-z0-9_]', '_', name) and truncate to 128.
- Map unfriendly external identifiers to safe internal ones (lookup table or hash suffix) instead of passing them through.
Example fix
# before CassandraDB(keyspace="my-keys", table="mem0", ...) # ValueError # after CassandraDB(keyspace="my_keys", table="mem0", ...)
Defensive patterns
Strategy: validation
Validate before calling
import re
_IDENT = re.compile(r"^[a-zA-Z_][a-zA-Z0-9_]{0,127}$")
def safe_cassandra_name(name: str, fallback: str = "mem0") -> str:
if not isinstance(name, str) or not _IDENT.match(name):
cleaned = re.sub(r"[^A-Za-z0-9_]", "_", str(name))[:120]
cleaned = re.sub(r"^[0-9]+", "", cleaned) or fallback
return cleaned.ljust(1, "_") if not cleaned else cleaned
return name
keyspace = safe_cassandra_name(tenant_id) Type guard
def is_safe_cassandra_identifier(name) -> bool:
import re
return isinstance(name, str) and bool(re.match(r"^[a-zA-Z_][a-zA-Z0-9_]{0,127}$", name)) Prevention
- Never derive keyspace/table names verbatim from hostnames, emails, or user IDs.
- Apply the sanitize helper at the API boundary where tenant names enter the system.
- Prefer a fixed keyspace with per-tenant collection/table prefixes that you control.
When it happens
Trigger: Constructing CassandraDB with a keyspace or table name containing a hyphen (my-keys), a dot (my.keyspace), a leading digit (2keys), an empty string, or longer than 128 chars. _validate_identifier is called in __init__ for both keyspace and collection/table arguments.
Common situations: Deriving keyspace/table names from user IDs, tenant names, or hostnames that contain hyphens/dots; copying a keyspace name from a CQL shell that quotes it with double quotes (quoting is what allows special chars in CQL, but this client forbids them).
Related errors
- Invalid {label}: {name!r}
- Invalid ${label} '${name}': only letters, digits, and unders
- Invalid ${label} '${name}': only letters, digits, and unders
- 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/4960deabf91f86f9.
Report an issue: GitHub.