cocoindex-io/cocoindex · error · ValueError
Invalid {kind}: {name!r}
Error message
Invalid {kind}: {name!r} What it means
The SQLite target validates table (and other) identifiers against `_IDENTIFIER_RE` before quoting, mirroring the Doris connector's defense against SQL injection via double quotes in identifiers (CVE-2026-28438). Any non-string or non-plain-identifier name raises this ValueError instead of being quoted.
Source
Thrown at python/cocoindex/connectors/sqlite/_target.py:162
# SQLite has a limit of 999 variables per query (SQLITE_MAX_VARIABLE_NUMBER)
_BIND_LIMIT: int = 999
_IDENTIFIER_RE = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")
def _validate_identifier(name: str, kind: str = "identifier") -> None:
"""Reject identifiers outside the unquoted-identifier allow-list.
SQLite identifiers are quoted with double quotes when interpolated, but
quoting alone does not prevent injection if the input itself contains a
double-quote character. Mirroring the Doris connector's approach
(CVE-2026-28438), we error out immediately on anything that isn't a plain
unquoted identifier.
"""
if not isinstance(name, str) or not _IDENTIFIER_RE.match(name):
raise ValueError(f"Invalid {kind}: {name!r}")
def _qualified_table_name(table_name: str) -> str:
"""Return a properly quoted table name."""
# SQLite uses double quotes for identifiers
return f'"{table_name}"'
class SqliteType(NamedTuple):
"""
Annotation to specify a SQLite column type.
Use with `typing.Annotated` to override the default type mapping:
```python
from typing import Annotated
from dataclasses import dataclass
from cocoindex.connectors.sqlite import SqliteTypeView on GitHub (pinned to e84aa99b32)
Solutions
- Sanitize the table name to a plain identifier: [A-Za-z_][A-Za-z0-9_]*.
- Replace path separators/dashes with underscores before creating the target.
- Convert non-str values (Path, bytes) with str()/decode before passing.
- Validate names with the same regex ahead of time to fail fast in your own config loading.
Example fix
// before
table = str(filepath.relative_to(root)) # 'docs/readme.md'
// after
table = str(filepath.relative_to(root)).replace('/', '_') # 'docs_readme_md' Defensive patterns
Strategy: validation
Validate before calling
import re
_IDENT = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")
def sqlite_table_name(raw: str) -> str:
name = re.sub(r"\W", "_", raw)
if not _IDENT.match(name):
raise ValueError(f"Cannot derive a safe table name from {raw!r}")
return name Type guard
import re
_IDENT = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")
def is_sqlite_identifier(name: object) -> TypeGuard[str]:
return isinstance(name, str) and bool(_IDENT.match(name)) Try / catch
try:
target = sqlite.table_target(table_name=name, ...)
except ValueError as e:
if e.args and e.args[0].startswith("Invalid "):
target = sqlite.table_target(table_name=re.sub(r"\W", "_", str(name)), ...)
else:
raise Prevention
- Slugify path-derived table names (replace '/' and '-' with '_').
- Never pass raw user input as a table name without normalization.
- Validate naming configuration when loading settings, not at sync time.
When it happens
Trigger: Calling `table_target` with a table name that is not a str, or contains characters like double quotes, spaces, dots, slashes, hyphens, or starts with a digit.
Common situations: Deriving table names from file paths (e.g. 'docs/readme.md'), using hyphenated slugs, or passing None/pathlib.Path instead of a str.
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 Snowflake {kind}: {name!r}
- VectorSchemaProvider is required for NumPy ndarray type.
- Invalid vector dimension: {vector_schema.size}
- VectorSchemaProvider is only supported for NumPy ndarray typ
- Primary key column '{pk}' not found in columns: {list(self.c
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/73766d5c08c96ce6.
Report an issue: GitHub.