{"record":{"id":"5493947ff25c0986","repo":"cocoindex-io/cocoindex","slug":"primary-key-column-primary-key-r-must-be-a-scala","errorCode":null,"errorMessage":"Primary key column {primary_key!r} must be a scalar field, got kind {columns[primary_key].kind!r}.","messagePattern":"Primary key column (.+?) must be a scalar field, got kind (.+?)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/cocoindex/connectors/zvec/_target.py","lineNumber":470,"sourceCode":"    row_type: type[RowT] | None\n\n    def __init__(\n        self,\n        columns: dict[str, _Column],\n        primary_key: str,\n        *,\n        row_type: type[RowT] | None = None,\n    ) -> None:\n        self.columns = columns\n        self.primary_key = primary_key\n        self.row_type = row_type\n        if primary_key not in columns:\n            raise ValueError(\n                f\"Primary key column {primary_key!r} not found in columns: \"\n                f\"{list(columns.keys())}\"\n            )\n        if columns[primary_key].kind != \"scalar\":\n            raise ValueError(\n                f\"Primary key column {primary_key!r} must be a scalar field, \"\n                f\"got kind {columns[primary_key].kind!r}.\"\n            )\n\n    @classmethod\n    async def from_class(\n        cls,\n        record_type: type[RowT],\n        primary_key: list[str],\n        *,\n        column_overrides: dict[\n            str,\n            ZvecType | ZvecVectorDef | ZvecFtsType | res_schema.VectorSchemaProvider,\n        ]\n        | None = None,\n    ) -> \"CollectionSchema[RowT]\":\n        \"\"\"Build a CollectionSchema from a record type.\n","sourceCodeStart":452,"sourceCodeEnd":488,"githubUrl":"https://github.com/cocoindex-io/cocoindex/blob/e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b/python/cocoindex/connectors/zvec/_target.py#L452-L488","documentation":"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__.","triggerScenarios":"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'.","commonSituations":"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.","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."],"exampleFix":"// before\nCollectionSpec(columns={\"id\": Column(kind=\"dense\", dim=768)}, primary_key=\"id\")\n// after\nCollectionSpec(columns={\"doc_id\": Column(kind=\"scalar\"), \"embedding\": Column(kind=\"dense\", dim=768)}, primary_key=\"doc_id\")","handlingStrategy":"validation","validationCode":"cols = schema.columns\nassert cols[schema.primary_key].kind == \"scalar\", \"primary key must be scalar\"","typeGuard":"def is_valid_pk(schema) -> bool:\n    pk = schema.columns.get(schema.primary_key)\n    return pk is not None and pk.kind == \"scalar\"","tryCatchPattern":null,"preventionTips":["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."],"tags":["python","vector-database","schema-validation","primary-key"],"backgroundTag":"schema-validation-failed","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"}