cocoindex-io/cocoindex · error · ValueError
Primary key column ' ' not found in columns
Error message
Primary key column '{pk}' not found in columns: {list(self.columns.keys())} What it means
Every column named in primary_key must exist among the table's declared columns; the primary key is emitted in SQL constraints against these columns. A missing name means the table definition is inconsistent, so __init__ raises ValueError.
Solutions
- Fix primary_key names to match the column names exactly.
- If using from_class, ensure the primary key names match dataclass field names.
- Add a missing field/column if it was unintentionally dropped.
Example fix
// before PgTableTarget.from_class(UserRow, primary_key=["uid"]) // after PgTableTarget.from_class(UserRow, primary_key=["id"]) # matches field name
Defensive patterns
Strategy: validation
Validate before calling
import dataclasses
fields = {f.name for f in dataclasses.fields(UserRow)}
assert set(primary_key) <= fields, f"PK columns missing: {set(primary_key) - fields}" Type guard
def primary_key_valid(row_type: type, primary_key: list[str]) -> bool:
names = {f.name for f in dataclasses.fields(row_type)}
return set(primary_key) <= names Try / catch
try:
target = await PgTableTarget.from_class(Row, primary_key=pk)
except ValueError as e:
if "not found in columns" in str(e):
raise ValueError(f"Fix primary_key; available: {list(get_column_names(Row))}") from e Prevention
- Keep primary_key lists in the same module as the row dataclass.
- Rename fields and primary keys in the same commit.
- Add a test asserting every pk name is a dataclass field.
When it happens
Trigger: Constructing PgTableTarget(columns=..., primary_key=['id']) where 'id' is not a key of the columns dict, e.g. after renaming a column or passing a raw column list from a different record type.
Common situations: Renaming dataclass fields without updating primary_key; typos in primary key names; sharing a primary_key list between tables with different schemas.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Invalid
- Primary key column not found in columns
- Azure Blob container client must expose account_name and…
- Cannot specify both an S3 URI and a separate key. Pass…
- Cannot specify both row_factory and row_type
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/ffad8f778d67c98c.
Report an issue: GitHub.
Appendix: source
Thrown at python/cocoindex/connectors/postgres/_target.py:359
"""
Create a TableSchema from pre-resolved column definitions.
For constructing from a record type, use the async classmethod
``from_class`` instead.
Args:
columns: A dict mapping column names to ColumnDef.
primary_key: List of column names that form the primary key.
row_type: Optional original record type.
"""
self.columns = columns
self.primary_key = primary_key
self.row_type = row_type
# Validate primary key columns exist
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, PgType | res_schema.VectorSchemaProvider]
| None = None,
) -> "TableSchema[RowT]":
"""
Create a TableSchema from a record type (dataclass, NamedTuple, or Pydantic model).
Python types are automatically mapped to PostgreSQL types based on asyncpg's
type conversion.
View on GitHub (pinned to e84aa99b32)