{"record":{"id":"66339f0f3064b588","repo":"cocoindex-io/cocoindex","slug":"invalid-snowflake-kind-name-r","errorCode":null,"errorMessage":"Invalid Snowflake {kind}: {name!r}","messagePattern":"Invalid Snowflake (.+?): (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/cocoindex/connectors/snowflake/_target.py","lineNumber":236,"sourceCode":"                annotation.encoder,\n                annotation.use_parse_json,\n            )\n\n    base_type = type_info.base_type\n    if base_type in _LEAF_TYPE_MAPPINGS:\n        return _LEAF_TYPE_MAPPINGS[base_type]\n\n    if isinstance(\n        type_info.variant, (SequenceType, MappingType, RecordType, UnionType, AnyType)\n    ):\n        return _VARIANT_MAPPING\n\n    return _VARIANT_MAPPING\n\n\ndef _validate_identifier(name: str, kind: str = \"identifier\") -> None:\n    if not isinstance(name, str) or not _IDENTIFIER_RE.match(name):\n        raise ValueError(f\"Invalid Snowflake {kind}: {name!r}\")\n\n\ndef _quote_ident(name: str) -> str:\n    _validate_identifier(name)\n    return f'\"{name}\"'\n\n\ndef _qualified_table_name(\n    database: str | None, schema: str | None, table_name: str\n) -> str:\n    parts = []\n    if database is not None:\n        parts.append(_quote_ident(database))\n    if schema is not None:\n        parts.append(_quote_ident(schema))\n    parts.append(_quote_ident(table_name))\n    return \".\".join(parts)\n","sourceCodeStart":218,"sourceCodeEnd":254,"githubUrl":"https://github.com/cocoindex-io/cocoindex/blob/e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b/python/cocoindex/connectors/snowflake/_target.py#L218-L254","documentation":"Snowflake identifiers (table, schema, database names) must match the connector's `_IDENTIFIER_RE` and be plain strings. The connector validates every identifier before double-quote quoting it, refusing anything else to prevent SQL injection through crafted identifiers. A non-matching name or non-string value raises this ValueError.","triggerScenarios":"Calling `_quote_ident` or `table_target` with a table/schema/database name that is not a string, or contains characters outside the allowed identifier pattern (e.g. spaces, dots, quotes, leading digits, hyphens).","commonSituations":"Building table names by f-string concatenation like f\"{prefix}-{suffix}\", deriving names from file paths with slashes, or passing a name that is accidentally bytes/None.","solutions":["Use only plain unquoted identifiers matching Snowflake rules (letters, digits, underscores, not starting with a digit).","Replace unsafe characters (hyphens, slashes, dots) with underscores before passing the name.","Coerce the name to str if it comes from a non-string source (path object, bytes).","If a reserved/irregular name is genuinely needed, pre-quote or rename — the connector intentionally does not accept them."],"exampleFix":"// before\ntable = f\"{dataset}-{date}\"  # contains hyphen\n// after\ntable = f\"{dataset}_{date}\".replace(\"-\", \"_\")","handlingStrategy":"validation","validationCode":"import re\n_IDENT = re.compile(r\"^[A-Za-z_][A-Za-z0-9_]*$\")\n\ndef check_snowflake_name(name: str) -> str:\n    if not isinstance(name, str) or not _IDENT.match(name):\n        raise ValueError(f\"Unsafe Snowflake identifier: {name!r}\")\n    return name\n\ncheck_snowflake_name(table_name)","typeGuard":"import re\n_IDENT = re.compile(r\"^[A-Za-z_][A-Za-z0-9_]*$\")\ndef is_safe_identifier(name: object) -> TypeGuard[str]:\n    return isinstance(name, str) and bool(_IDENT.match(name))","tryCatchPattern":"try:\n    target = snowflake.table_target(name=table_name, ...)\nexcept ValueError as e:\n    if e.args and e.args[0].startswith(\"Invalid Snowflake\"):\n        table_name = re.sub(r\"\\W\", \"_\", str(table_name))\n        target = snowflake.table_target(name=table_name, ...)\n    else:\n        raise","preventionTips":["Generate table names with a sanitizer: re.sub(r'\\W', '_', name).","Never build identifiers from raw user or file-path input without normalization.","Validate all naming config at startup, before opening targets."],"tags":["snowflake","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"}