{"record":{"id":"f9af90c8a9f109b4","repo":"mem0ai/mem0","slug":"invalid-label-name-only-letters-digits-an","errorCode":null,"errorMessage":"Invalid {label} '{name}': only letters, digits, and underscores are allowed, must start with a letter or underscore, and be at most 128 characters.","messagePattern":"Invalid (.+?) '(.+?)': only letters, digits, and underscores are allowed, must start with a letter or underscore, and be at most 128 characters\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"mem0/vector_stores/azure_mysql.py","lineNumber":34,"sourceCode":"        \"Please install them using 'pip install pymysql dbutils'\"\n    )\n\ntry:\n    from azure.identity import DefaultAzureCredential\n    AZURE_IDENTITY_AVAILABLE = True\nexcept ImportError:\n    AZURE_IDENTITY_AVAILABLE = False\n\nfrom mem0.vector_stores.base import VectorStoreBase\n\nlogger = logging.getLogger(__name__)\n\n_SAFE_IDENTIFIER_RE = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]{0,127}$')\n\n\ndef _validate_identifier(name: str, label: str = \"identifier\") -> str:\n    if not _SAFE_IDENTIFIER_RE.match(name):\n        raise ValueError(\n            f\"Invalid {label} '{name}': only letters, digits, and underscores are allowed, \"\n            \"must start with a letter or underscore, and be at most 128 characters.\"\n        )\n    return name\n\n# Filter keys are interpolated into `JSON_EXTRACT(payload, '$.<key>')` strings,\n# so we whitelist identifier-safe keys and skip anything else (logged as a warning).\n_VALID_FILTER_KEY = re.compile(r\"^[A-Za-z_][A-Za-z0-9_]*$\")\n\n\nclass OutputData(BaseModel):\n    id: Optional[str]\n    score: Optional[float]\n    payload: Optional[dict]\n\n\nclass AzureMySQL(VectorStoreBase):\n    def __init__(","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/mem0ai/mem0/blob/001c235229be8795e3834520467bd0d661ed8f34/mem0/vector_stores/azure_mysql.py#L16-L52","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","solutions":["Rename the identifier: replace hyphens/dots with underscores (mem0-prod → mem0_prod)","Ensure it starts with a letter or underscore and only uses [A-Za-z0-9_]","Keep it ≤128 characters","If the name derives from a UUID, strip hyphens: uid.replace('-', '_')"],"exampleFix":"# before\nvs_cfg = {\"provider\": \"azure_mysql\", \"config\": {\n  \"database_name\": \"mem0-prod\", \"collection_name\": \"user-123-memories\"}}\n\n# after\nvs_cfg = {\"provider\": \"azure_mysql\", \"config\": {\n  \"database_name\": \"mem0_prod\", \"collection_name\": \"user_123_memories\"}}","handlingStrategy":"validation","validationCode":"import re\nSAFE = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]{0,127}$')\nfor label, name in (('database_name', cfg['database_name']), ('collection_name', cfg['collection_name'])):\n    if not SAFE.match(name):\n        raise ConfigError(f'{label}={name!r} must match [A-Za-z_][A-Za-z0-9_]{0,127}')","typeGuard":"def is_safe_mysql_identifier(name) -> bool:\n    import re\n    return isinstance(name, str) and re.fullmatch(r'[a-zA-Z_][a-zA-Z0-9_]{0,127}', name) is not None","tryCatchPattern":"try:\n    memory = Memory.from_config(cfg)\nexcept ValueError as e:\n    if 'only letters, digits, and underscores' in str(e):\n        cfg['vector_store']['config']['collection_name'] = re.sub(r'[^A-Za-z0-9_]', '_', raw_name).lstrip('0123456789')\n        memory = Memory.from_config(cfg)\n    else:\n        raise","preventionTips":["Generate table/database names from [A-Za-z0-9_] only; map hyphens to underscores at config-build time","Never interpolate user/tenant ids containing dashes (UUIDs) directly into collection names","Centralize identifier sanitization in your config layer and unit-test it"],"tags":["azure","mysql","identifier-validation","sql-injection","configuration"],"backgroundTag":null,"analyzedSha":"001c235229be8795e3834520467bd0d661ed8f34","analyzedAt":"2026-08-15T01:55:42.685Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}