cocoindex-io/cocoindex · error · ValueError
{label} must contain only alphanumeric characters, hyphens,
Error message
{label} must contain only alphanumeric characters, hyphens, and underscores, got: {value!r} What it means
Valkey index/doc names are embedded into hash keys (`_make_hash_key`) and into the FT.SEARCH/FT.CREATE DSL, so characters like spaces, colons, and braces could cause key collisions or DSL injection. `_validate_name` enforces `_SAFE_NAME_RE` (alphanumerics, hyphens, underscores) and raises this ValueError naming the offending label and value.
Source
Thrown at python/cocoindex/connectors/valkey/_target.py:251
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
_SAFE_NAME_RE = re.compile(r"^[a-zA-Z0-9_\-]+$")
_VECTOR_FIELD_NAME = "vector"
def _validate_name(value: str, label: str) -> str:
"""Validate that a name contains only safe characters.
Raises:
ValueError: If the name contains characters that could cause key
collisions or injection into the Valkey search DSL.
"""
if not _SAFE_NAME_RE.match(value):
raise ValueError(
f"{label} must contain only alphanumeric characters, "
f"hyphens, and underscores, got: {value!r}"
)
return value
def _vector_to_bytes(vector: list[float] | np.ndarray) -> bytes: # type: ignore[type-arg]
"""Pack a vector into little-endian float32 bytes for Valkey HASH storage."""
if isinstance(vector, np.ndarray):
return vector.astype(np.float32).tobytes()
return struct.pack(f"<{len(vector)}f", *vector)
def _make_prefix(index_name: str) -> str:
"""Create the key prefix for documents in an index."""
return f"{index_name}:"
View on GitHub (pinned to e84aa99b32)
Solutions
- Sanitize the name before passing it: re.sub(r'[^A-Za-z0-9_-]', '_', value) or a similar whitelist.
- Replace ':' separators with '-' or '_' (e.g. 'ns-docs' instead of 'ns:docs').
- For doc ids, hash or encode unsafe identifiers: _validate_name accepts only [A-Za-z0-9_-], so slugify or hashlib.sha256 the raw id.
Example fix
// before
index_target(name=f"{tenant}:{env}")
// after
safe = re.sub(r"[^A-Za-z0-9_-]", "_", f"{tenant}-{env}")
index_target(name=safe) Defensive patterns
Strategy: validation
Validate before calling
import re
_SAFE = re.compile(r"^[A-Za-z0-9_-]+$")
assert _SAFE.match(name), f"Unsafe Valkey name: {name!r}" Try / catch
try:
target = await valkey.index_target(name=name)
except ValueError as e:
if "must contain only alphanumeric" in str(e):
name = re.sub(r"[^A-Za-z0-9_-]", "_", name)
target = await valkey.index_target(name=name)
else:
raise Prevention
- Slugify any name derived from filenames, tenants, or user input before passing it in
- Avoid ':' namespace conventions from Redis — use '-' or '_' here
- Add a pre-commit/test asserting generated index names match ^[A-Za-z0-9_-]+$
When it happens
Trigger: Calling `index_target(name="my index")`, `name="ns:docs"`, or `name="docs{0}"`, or reconcile with a doc_id containing spaces/colons — anywhere `_validate_name` runs on index names or doc ids.
Common situations: Deriving index names from filenames or user input ('My Docs 2024'); using namespace-style 'prefix:name' conventions carried over from Redis; doc ids built from URLs or paths containing ':' and '/'.
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 {kind}: {name!r}
- Invalid collection name {name!r}: zvec requires at least {_M
- expected None{loc}, got {type(value).__name__}
- expected {tp}{loc}, got {type(value).__name__}: {value!r}
- expected tuple{loc}, got {type(value).__name__}
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/b19b13ca2099a8fb.
Report an issue: GitHub.