cocoindex-io/cocoindex · error · ValueError
Primary key column {primary_key!r} must be a scalar field, g
Error message
Primary key column {primary_key!r} must be a scalar field, got kind {columns[primary_key].kind!r}. What it means
The zvec collection target validates, at construction, that the column designated as the primary key is a scalar field, because the primary-key value is converted to a string and used as the document id. If the chosen column is a vector (dense/sparse) or other non-scalar kind, no valid document id can be derived, so a ValueError is raised in __init__.
Source
Thrown at python/cocoindex/connectors/zvec/_target.py:470
row_type: type[RowT] | None
def __init__(
self,
columns: dict[str, _Column],
primary_key: str,
*,
row_type: type[RowT] | None = None,
) -> None:
self.columns = columns
self.primary_key = primary_key
self.row_type = row_type
if primary_key not in columns:
raise ValueError(
f"Primary key column {primary_key!r} not found in columns: "
f"{list(columns.keys())}"
)
if columns[primary_key].kind != "scalar":
raise ValueError(
f"Primary key column {primary_key!r} must be a scalar field, "
f"got kind {columns[primary_key].kind!r}."
)
@classmethod
async def from_class(
cls,
record_type: type[RowT],
primary_key: list[str],
*,
column_overrides: dict[
str,
ZvecType | ZvecVectorDef | ZvecFtsType | res_schema.VectorSchemaProvider,
]
| None = None,
) -> "CollectionSchema[RowT]":
"""Build a CollectionSchema from a record type.
View on GitHub (pinned to e84aa99b32)
Solutions
- Set primary_key to a column declared with kind 'scalar' (e.g. an int/str id field).
- Add a scalar id column to your record type and use it as primary_key.
- If using from_class, ensure the dataclass/NamedTuple has a scalar field (str/int) and pass its name as primary_key.
Example fix
// before
CollectionSpec(columns={"id": Column(kind="dense", dim=768)}, primary_key="id")
// after
CollectionSpec(columns={"doc_id": Column(kind="scalar"), "embedding": Column(kind="dense", dim=768)}, primary_key="doc_id") Defensive patterns
Strategy: validation
Validate before calling
cols = schema.columns assert cols[schema.primary_key].kind == "scalar", "primary key must be scalar"
Type guard
def is_valid_pk(schema) -> bool:
pk = schema.columns.get(schema.primary_key)
return pk is not None and pk.kind == "scalar" Prevention
- Always use a str/int scalar field as primary_key.
- Never point primary_key at a vector column.
- Validate the schema before declaring a collection target.
When it happens
Trigger: Constructing _CollectionSpec (or declaring a zvec collection target) with primary_key set to a column whose schema kind is 'dense' or 'sparse' instead of 'scalar'.
Common situations: Pointing primary_key at a vector/embedding column by mistake; auto-generating primary_key from field inference when the dataclass only has a vector field; renaming a scalar id column to a vector column after a schema change.
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
- zvec collections require exactly one primary key column (map
- Primary key column '{pk}' not found in columns: {list(self.c
- Primary key {schema.primary_key!r} value cannot be None.
- zvec collections require at least one vector field (dense or
- Primary key column '{pk}' not found in columns: {list(self.c
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/5493947ff25c0986.
Report an issue: GitHub.