cocoindex-io/cocoindex · error
build_node_upsert requires at least one primary key field
Error message
build_node_upsert requires at least one primary key field
What it means
build_node_upsert() refuses to build a MERGE query when pk_fields is empty. A MERGE needs at least one key property to identify the node uniquely; without primary key fields the upsert would match every node or be meaningless, so the library fails fast instead of generating a broken Cypher query.
Source
Thrown at python/cocoindex/connectors/falkordb/_cypher.py:76
(e.g. ``var="n"`` makes it clear this clause attaches to ``n``).
"""
parts = [f"{_quote(f)}: ${prefix}_{i}" for i, f in enumerate(fields)]
return "{" + ", ".join(parts) + "}"
def build_node_upsert(
label: str,
pk_fields: Sequence[str],
has_value_fields: bool,
) -> str:
"""``MERGE (n:`Label` {pk: $key_0, ...}) [SET n += $props]``.
``has_value_fields`` controls whether the ``SET n += $props`` clause is
emitted. Caller passes ``True`` when there is at least one non-PK column to
write; otherwise the MERGE alone suffices.
"""
if not pk_fields:
raise ValueError("build_node_upsert requires at least one primary key field")
cypher = f"MERGE (n:{_quote(label)} {_key_clause('key', pk_fields, 'n')})"
if has_value_fields:
cypher += " SET n += $props"
return cypher
def build_node_delete(label: str, pk_fields: Sequence[str]) -> str:
"""``MATCH (n:`Label` {pk: $key_0, ...}) DETACH DELETE n``.
DETACH DELETE removes any incident edges as a safety measure for nodes that
are also referenced as relationship endpoints — without it, the DELETE
would fail on nodes that still have edges.
"""
if not pk_fields:
raise ValueError("build_node_delete requires at least one primary key field")
return (
f"MATCH (n:{_quote(label)} {_key_clause('key', pk_fields, 'n')}) "
f"DETACH DELETE n"View on GitHub (pinned to e84aa99b32)
Solutions
- Declare at least one primary key field in the node table schema (e.g. the unique 'id' column) and pass it in pk_fields.
- Check the code that builds the pk_fields list — a filter or optional config may be dropping the key fields.
- If the node truly has no natural key, designate a deterministic unique property (e.g. content hash) as the primary key.
Example fix
// before build_node_upsert(label="Person", pk_fields=[], value_fields=["name"]) // after build_node_upsert(label="Person", pk_fields=["person_id"], value_fields=["name"])
Defensive patterns
Strategy: validation
Validate before calling
if not pk_fields:
raise ValueError('node table needs at least one primary key field before upsert')
# proceed with build_node_upsert(label, pk_fields, ...) Type guard
def has_pk_fields(pk_fields: object) -> bool:
return isinstance(pk_fields, (list, tuple)) and len(pk_fields) > 0 Try / catch
try:
cypher = build_node_upsert(label, pk_fields, has_value_fields)
except ValueError as e:
logger.error('node upsert misconfigured: %s', e)
raise ConfigError(f'table {label!r} must declare a primary key field') from e Prevention
- Always designate exactly one unique key column in every node table schema.
- When building pk_fields programmatically, assert non-empty before calling the builder.
- Use a deterministic key (e.g. content hash) for data without a natural unique id.
When it happens
Trigger: Calling build_node_upsert(label, pk_fields=[], ...) — i.e. declaring a node table/handler with no primary key fields configured.
Common situations: Schema definition omitted the primary key (e.g. forgot to mark 'id' as a key column); a table maps only non-key value columns; a key fields list was built programmatically and filtered to empty.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- build_node_delete requires at least one primary key field
- build_relationship_upsert requires PK fields for from, to, a
- build_node_index_create requires at least one field
- primary_key {primary_key!r} not found in columns ({sorted(co
- 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/293ebf1869c0813d.
Report an issue: GitHub.