cocoindex-io/cocoindex · error · ValueError

Invalid Snowflake {kind}: {name!r}

Error message

Invalid Snowflake {kind}: {name!r}

What it means

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.

Source

Thrown at python/cocoindex/connectors/snowflake/_target.py:236

                annotation.encoder,
                annotation.use_parse_json,
            )

    base_type = type_info.base_type
    if base_type in _LEAF_TYPE_MAPPINGS:
        return _LEAF_TYPE_MAPPINGS[base_type]

    if isinstance(
        type_info.variant, (SequenceType, MappingType, RecordType, UnionType, AnyType)
    ):
        return _VARIANT_MAPPING

    return _VARIANT_MAPPING


def _validate_identifier(name: str, kind: str = "identifier") -> None:
    if not isinstance(name, str) or not _IDENTIFIER_RE.match(name):
        raise ValueError(f"Invalid Snowflake {kind}: {name!r}")


def _quote_ident(name: str) -> str:
    _validate_identifier(name)
    return f'"{name}"'


def _qualified_table_name(
    database: str | None, schema: str | None, table_name: str
) -> str:
    parts = []
    if database is not None:
        parts.append(_quote_ident(database))
    if schema is not None:
        parts.append(_quote_ident(schema))
    parts.append(_quote_ident(table_name))
    return ".".join(parts)

View on GitHub (pinned to e84aa99b32)

Solutions

  1. Use only plain unquoted identifiers matching Snowflake rules (letters, digits, underscores, not starting with a digit).
  2. Replace unsafe characters (hyphens, slashes, dots) with underscores before passing the name.
  3. Coerce the name to str if it comes from a non-string source (path object, bytes).
  4. If a reserved/irregular name is genuinely needed, pre-quote or rename — the connector intentionally does not accept them.

Example fix

// before
table = f"{dataset}-{date}"  # contains hyphen
// after
table = f"{dataset}_{date}".replace("-", "_")
Defensive patterns

Strategy: validation

Validate before calling

import re
_IDENT = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")

def check_snowflake_name(name: str) -> str:
    if not isinstance(name, str) or not _IDENT.match(name):
        raise ValueError(f"Unsafe Snowflake identifier: {name!r}")
    return name

check_snowflake_name(table_name)

Type guard

import re
_IDENT = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")
def is_safe_identifier(name: object) -> TypeGuard[str]:
    return isinstance(name, str) and bool(_IDENT.match(name))

Try / catch

try:
    target = snowflake.table_target(name=table_name, ...)
except ValueError as e:
    if e.args and e.args[0].startswith("Invalid Snowflake"):
        table_name = re.sub(r"\W", "_", str(table_name))
        target = snowflake.table_target(name=table_name, ...)
    else:
        raise

Prevention

When it happens

Trigger: 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).

Common situations: 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.

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


AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08). Data as JSON: /api/errors/66339f0f3064b588. Report an issue: GitHub.