{"record":{"id":"73766d5c08c96ce6","repo":"cocoindex-io/cocoindex","slug":"invalid-kind-name-r-73766d","errorCode":null,"errorMessage":"Invalid {kind}: {name!r}","messagePattern":"Invalid (.+?): (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/cocoindex/connectors/sqlite/_target.py","lineNumber":162,"sourceCode":"\n# SQLite has a limit of 999 variables per query (SQLITE_MAX_VARIABLE_NUMBER)\n_BIND_LIMIT: int = 999\n\n\n_IDENTIFIER_RE = re.compile(r\"^[A-Za-z_][A-Za-z0-9_]*$\")\n\n\ndef _validate_identifier(name: str, kind: str = \"identifier\") -> None:\n    \"\"\"Reject identifiers outside the unquoted-identifier allow-list.\n\n    SQLite identifiers are quoted with double quotes when interpolated, but\n    quoting alone does not prevent injection if the input itself contains a\n    double-quote character. Mirroring the Doris connector's approach\n    (CVE-2026-28438), we error out immediately on anything that isn't a plain\n    unquoted identifier.\n    \"\"\"\n    if not isinstance(name, str) or not _IDENTIFIER_RE.match(name):\n        raise ValueError(f\"Invalid {kind}: {name!r}\")\n\n\ndef _qualified_table_name(table_name: str) -> str:\n    \"\"\"Return a properly quoted table name.\"\"\"\n    # SQLite uses double quotes for identifiers\n    return f'\"{table_name}\"'\n\n\nclass SqliteType(NamedTuple):\n    \"\"\"\n    Annotation to specify a SQLite column type.\n\n    Use with `typing.Annotated` to override the default type mapping:\n\n    ```python\n    from typing import Annotated\n    from dataclasses import dataclass\n    from cocoindex.connectors.sqlite import SqliteType","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/cocoindex-io/cocoindex/blob/e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b/python/cocoindex/connectors/sqlite/_target.py#L144-L180","documentation":"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.","triggerScenarios":"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.","commonSituations":"Deriving table names from file paths (e.g. 'docs/readme.md'), using hyphenated slugs, or passing None/pathlib.Path instead of a str.","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."],"exampleFix":"// before\ntable = str(filepath.relative_to(root))  # 'docs/readme.md'\n// after\ntable = str(filepath.relative_to(root)).replace('/', '_')  # 'docs_readme_md'","handlingStrategy":"validation","validationCode":"import re\n_IDENT = re.compile(r\"^[A-Za-z_][A-Za-z0-9_]*$\")\n\ndef sqlite_table_name(raw: str) -> str:\n    name = re.sub(r\"\\W\", \"_\", raw)\n    if not _IDENT.match(name):\n        raise ValueError(f\"Cannot derive a safe table name from {raw!r}\")\n    return name","typeGuard":"import re\n_IDENT = re.compile(r\"^[A-Za-z_][A-Za-z0-9_]*$\")\ndef is_sqlite_identifier(name: object) -> TypeGuard[str]:\n    return isinstance(name, str) and bool(_IDENT.match(name))","tryCatchPattern":"try:\n    target = sqlite.table_target(table_name=name, ...)\nexcept ValueError as e:\n    if e.args and e.args[0].startswith(\"Invalid \"):\n        target = sqlite.table_target(table_name=re.sub(r\"\\W\", \"_\", str(name)), ...)\n    else:\n        raise","preventionTips":["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."],"tags":["sqlite","sql-injection","identifier-validation"],"backgroundTag":"invalid-identifier-format","analyzedSha":"e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b","analyzedAt":"2026-09-08T15:59:19.997Z","contentChangedAt":"2026-09-08T15:59:19.997Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}