cocoindex-io/cocoindex · error · ValueError
Invalid SurrealDB {kind}: {name!r}. Must match [a-zA-Z_][a-z
Error message
Invalid SurrealDB {kind}: {name!r}. Must match [a-zA-Z_][a-zA-Z0-9_]*. What it means
SurrealQL identifiers (table names, index names, column names) used inline in generated SurrealQL must be safe: start with a letter or underscore and contain only alphanumerics/underscores. CocoIndex validates all such names up front (in __init__, declare_vector_index, table_target, relation_target) to prevent syntax errors and injection via crafted names.
Source
Thrown at python/cocoindex/connectors/surrealdb/_target.py:81
from cocoindex.resources import schema as res_schema
from cocoindex._internal.context_keys import ContextKey, ContextProvider
# ---------------------------------------------------------------------------
# Identifier validation & record ID formatting
# ---------------------------------------------------------------------------
_IDENTIFIER_RE = re.compile(r"^[a-zA-Z_][a-zA-Z0-9_]*$")
def _validate_identifier(name: str, kind: str) -> None:
"""Validate that *name* is a safe SurrealQL identifier.
Raises :class:`ValueError` if the name contains characters that are not
alphanumeric or underscore, or starts with a digit.
"""
if not _IDENTIFIER_RE.match(name):
raise ValueError(
f"Invalid SurrealDB {kind}: {name!r}. Must match [a-zA-Z_][a-zA-Z0-9_]*."
)
def _format_record_id(value: Any) -> str:
"""Format a record ID for inline use in SurrealQL, preserving type.
* ``int`` / ``float`` → bare numeric literal (``123``, ``3.14``)
* ``str`` (and everything else) → backtick-quoted with ``\\`` and
backtick escaping (`` `alice` ``, `` `has\\`tick` ``)
"""
if isinstance(value, (int, float)):
return str(value)
s = str(value)
s = s.replace("\\", "\\\\").replace("`", "\\`")
return f"`{s}`"
View on GitHub (pinned to e84aa99b32)
Solutions
- Rename to a valid identifier: letters/underscore first, then alphanumerics/underscores only (e.g. 'my_table').
- Sanitize derived names programmatically before passing them (replace invalid chars with '_').
- Quote/escape is not offered by this API surface, so renaming is the only path.
Example fix
// before relation_target(name="my-table", ...) // after relation_target(name="my_table", ...)
Defensive patterns
Strategy: validation
Validate before calling
import re
_IDENT = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
def assert_valid_name(name: str) -> None:
if not _IDENT.match(name):
raise ValueError(f"invalid SurrealDB identifier: {name!r}") Type guard
def is_safe_identifier(name: str) -> bool:
import re
return bool(re.fullmatch(r"[a-zA-Z_][a-zA-Z0-9_]*", name)) Try / catch
try:
target = relation_target(name=user_supplied_name, ...)
except ValueError as e:
if "Invalid SurrealDB" in str(e):
name = re.sub(r"\W", "_", user_supplied_name)
target = relation_target(name=name, ...) Prevention
- Sanitize names derived from file paths or user input before creating targets.
- Enforce snake_case naming conventions for tables and indexes.
- Validate names in a shared helper instead of passing raw strings around.
When it happens
Trigger: Creating a relation_target/table_target or declaring a vector index with a name containing hyphens, dots, spaces, digits at position 0, or other non-identifier characters, e.g. table name 'my-table' or an index named 'idx.embedding'.
Common situations: Deriving table names from file paths or user input ('docs-2024'); using dotted or dashed names common in other databases; generating names programmatically without sanitizing.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Invalid BigQuery {kind}: {name!r}
- Invalid identifier: {name}
- Invalid FalkorDB {kind}: {name!r}. Must match [a-zA-Z_][a-zA
- Invalid Neo4j database name: {database!r}. Must match [A-Za-
- {identifier_type} cannot be empty
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/938edfe18618f2f1.
Report an issue: GitHub.