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

Raised by _validate_identifier in mem0/vector_stores/azure_mysql.py when a database/table identifier (e.g. database_name or collection/table name from vector store config) does not match ^[a-zA-Z_][a-zA-Z0-9_]{0,127}$. Because identifiers are interpolated into raw SQL DDL, mem0 whitelists ASCII letters, digits, and underscores, requires a non-digit first character, and caps length at 128 — a SQL-injection guard.

Source

Thrown at mem0/vector_stores/azure_mysql.py:34

        "Please install them using 'pip install pymysql dbutils'"
    )

try:
    from azure.identity import DefaultAzureCredential
    AZURE_IDENTITY_AVAILABLE = True
except ImportError:
    AZURE_IDENTITY_AVAILABLE = False

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

# Filter keys are interpolated into `JSON_EXTRACT(payload, '$.<key>')` strings,
# so we whitelist identifier-safe keys and skip anything else (logged as a warning).
_VALID_FILTER_KEY = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")


class OutputData(BaseModel):
    id: Optional[str]
    score: Optional[float]
    payload: Optional[dict]


class AzureMySQL(VectorStoreBase):
    def __init__(

View on GitHub (pinned to 001c235229)

Solutions

  1. Rename the identifier: replace hyphens/dots with underscores (mem0-prod → mem0_prod)
  2. Ensure it starts with a letter or underscore and only uses [A-Za-z0-9_]
  3. Keep it ≤128 characters
  4. If the name derives from a UUID, strip hyphens: uid.replace('-', '_')

Example fix

# before
vs_cfg = {"provider": "azure_mysql", "config": {
  "database_name": "mem0-prod", "collection_name": "user-123-memories"}}

# after
vs_cfg = {"provider": "azure_mysql", "config": {
  "database_name": "mem0_prod", "collection_name": "user_123_memories"}}
Defensive patterns

Strategy: validation

Validate before calling

import re
SAFE = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]{0,127}$')
for label, name in (('database_name', cfg['database_name']), ('collection_name', cfg['collection_name'])):
    if not SAFE.match(name):
        raise ConfigError(f'{label}={name!r} must match [A-Za-z_][A-Za-z0-9_]{0,127}')

Type guard

def is_safe_mysql_identifier(name) -> bool:
    import re
    return isinstance(name, str) and re.fullmatch(r'[a-zA-Z_][a-zA-Z0-9_]{0,127}', name) is not None

Try / catch

try:
    memory = Memory.from_config(cfg)
except ValueError as e:
    if 'only letters, digits, and underscores' in str(e):
        cfg['vector_store']['config']['collection_name'] = re.sub(r'[^A-Za-z0-9_]', '_', raw_name).lstrip('0123456789')
        memory = Memory.from_config(cfg)
    else:
        raise

Prevention

When it happens

Trigger: Setting collection_name or database_name to a value with hyphens (mem0-prod), dots (db.mem0), spaces, unicode, leading digits (1db), or longer than 128 chars; passing an env-derived name like 'mem0_${env}' with the placeholder unsubstituted; passing a quoted name 'my-table' including quote characters.

Common situations: Defaulting the table name to the app name ('my-app-memories') which contains hyphens; copying database names from Azure Portal that include resource-group-qualified strings; names generated from user/tenant ids containing dashes (UUIDs).

Related errors


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