{"record":{"id":"e623098a05bccf26","repo":"cocoindex-io/cocoindex","slug":"row-is-missing-primary-key-field-self-primary-ke-e62309","errorCode":null,"errorMessage":"row is missing primary key field {self._primary_key!r}","messagePattern":"row is missing primary key field (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/cocoindex/connectors/neo4j/_target.py","lineNumber":1247,"sourceCode":"    ) -> None:\n        self._provider = provider\n        self._table_schema = table_schema\n        self._table_name = table_name\n        self._primary_key = primary_key\n\n    @property\n    def table_name(self) -> str:\n        return self._table_name\n\n    @property\n    def primary_key(self) -> str:\n        return self._primary_key\n\n    def declare_record(self: TableTarget[RowT], *, row: RowT) -> None:\n        \"\"\"Declare a record (node) to be upserted to this table.\"\"\"\n        row_dict = self._row_to_dict(row)\n        if self._primary_key not in row_dict:\n            raise ValueError(f\"row is missing primary key field {self._primary_key!r}\")\n        pk_values = (row_dict[self._primary_key],)\n        coco.declare_target_state(self._provider.target_state(pk_values, row_dict))\n\n    declare_row = declare_record\n\n    def _row_to_dict(self, row: RowT) -> dict[str, Any]:\n        if self._table_schema is not None:\n            out: dict[str, Any] = {}\n            for col_name, col in self._table_schema.columns.items():\n                if isinstance(row, dict):\n                    value = row.get(col_name)\n                else:\n                    value = getattr(row, col_name)\n                if value is not None and col.encoder is not None:\n                    value = col.encoder(value)\n                out[col_name] = value\n            return out\n        if isinstance(row, dict):","sourceCodeStart":1229,"sourceCodeEnd":1265,"githubUrl":"https://github.com/cocoindex-io/cocoindex/blob/e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b/python/cocoindex/connectors/neo4j/_target.py#L1229-L1265","documentation":"Neo4j's TableTarget.declare_record() converts the row to a dict and requires the configured primary key field to be present, since the primary key value identifies the node to upsert. If the row dict lacks that field, no node key can be computed and the library raises ValueError instead of writing an incomplete record.","triggerScenarios":"Calling table_target.declare_record(row=...) (or declare_row) with a row object/dict whose serialized form does not contain a key equal to the table's primary_key (default \"id\").","commonSituations":"Using a dataclass or dict with a differently named key (e.g. \"key\" or \"node_id\") while the table was declared with primary_key=\"id\"; forgetting to include the PK in dicts built dynamically; renaming the schema field without updating primary_key.","solutions":["Add the primary key field to the row object/dict you pass to declare_record.","Declare the table with primary_key=<your actual field name> so it matches the row's key.","Check what _row_to_dict produces (e.g. dataclass asdict) and confirm the field name spelling/case matches primary_key exactly."],"exampleFix":"// before\ntarget.declare_row(row={\"node_id\": 7, \"name\": \"Alice\"})\n// after\ntarget.declare_row(row={\"id\": 7, \"name\": \"Alice\"})  # or declare table with primary_key=\"node_id\"","handlingStrategy":"validation","validationCode":"pk = target._primary_key if hasattr(target, \"_primary_key\") else \"id\"\nrow_dict = row if isinstance(row, dict) else dataclasses.asdict(row)\nif pk not in row_dict:\n    raise ValueError(f\"row missing primary key field {pk!r}\")\ntarget.declare_record(row=row)","typeGuard":"def has_pk(row: dict, pk: str) -> bool:\n    return isinstance(row, dict) and pk in row","tryCatchPattern":null,"preventionTips":["Keep the row's PK field name and the table's primary_key argument defined from one shared constant.","For dataclasses, ensure the PK is a declared field so _row_to_dict includes it.","Prefer schema-driven tables (pass table_schema) so the PK has a single source of truth."],"tags":["neo4j","validation","primary-key"],"backgroundTag":"missing-required-argument","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"}