cocoindex-io/cocoindex · error · ValueError

Primary key column '{pk}' not found in columns: {list(self.c

Error message

Primary key column '{pk}' not found in columns: {list(self.columns.keys())}

What it means

The Snowflake target connector requires every primary key column to exist in the declared columns dict. In __init__ of the target (table) definition, each name in primary_key is checked against columns; a missing name raises this ValueError listing the columns that DO exist, so the mismatch is immediately visible.

Source

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

    columns: dict[str, ColumnDef]
    primary_key: list[str]
    row_type: type[RowT] | None

    def __init__(
        self,
        columns: dict[str, ColumnDef],
        primary_key: list[str],
        *,
        row_type: type[RowT] | None = None,
    ) -> None:
        self.columns = columns
        self.primary_key = primary_key
        self.row_type = row_type

        for pk in self.primary_key:
            if pk not in self.columns:
                raise ValueError(
                    f"Primary key column '{pk}' not found in columns: {list(self.columns.keys())}"
                )

    @classmethod
    async def from_class(
        cls,
        record_type: type[RowT],
        primary_key: list[str],
        *,
        column_overrides: dict[str, SnowflakeType] | None = None,
    ) -> "TableSchema[RowT]":
        """
        Create a TableSchema from a record type.

        Args:
            record_type: A dataclass, NamedTuple, or Pydantic model.
            primary_key: List of column names that form the primary key.
            column_overrides: Optional per-column SnowflakeType overrides.

View on GitHub (pinned to e84aa99b32)

Solutions

  1. Compare the message's column list with your primary_key and fix the typo/case so the PK name matches a declared column exactly.
  2. Add the missing column to the columns/row_type definition if it should be part of the schema.
  3. Remove the stale PK entry if that column is no longer part of the key.
  4. Remember Snowflake stores unquoted identifiers uppercase — make the declared name match how the column is actually defined.

Example fix

// before
TableTarget(columns={"id": IntegerType(), "name": TextType()}, primary_key=["doc_id"])
// after
TableTarget(columns={"id": IntegerType(), "name": TextType()}, primary_key=["id"])
Defensive patterns

Strategy: validation

Validate before calling

missing = set(primary_key) - set(columns)
assert not missing, f"PK columns not declared: {missing}"

Type guard

all(pk in columns for pk in primary_key)

Try / catch

try:
    target = SnowflakeTableTarget(columns=cols, primary_key=pk)
except ValueError as e:
    raise SchemaError(f"snowflake PK mismatch: {e}") from None

Prevention

When it happens

Trigger: Constructing the Snowflake table target with a primary_key list containing a column name absent from `columns` — e.g. a typo, a case mismatch ('ID' vs 'id'), or a PK column defined only in the external table but not in the declared row type.

Common situations: Renaming a column in the schema but not in primary_key; Snowflake identifier case (unquoted identifiers are upper-cased by Snowflake) causing 'id' vs 'ID' mismatch; PK config copied from another table's definition.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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