cocoindex-io/cocoindex · error · ValueError

build_node_index_create requires at least one field

Error message

build_node_index_create requires at least one field

What it means

build_node_index_create generates CREATE INDEX ... FOR (n:Label) ON (n.f1, n.f2, ...). Neo4j indexes require at least one indexed property; an empty fields list would produce invalid DDL, so it raises ValueError.

Source

Thrown at python/cocoindex/connectors/neo4j/_cypher.py:173

        raise ValueError(
            "build_relationship_delete requires at least one primary key field"
        )
    return (
        f"MATCH ()-[r:{_quote(rel_type)} {_key_clause('key', pk_fields)}]->() DELETE r"
    )


def build_node_index_create(
    name: str,
    label: str,
    fields: Sequence[str],
) -> str:
    """``CREATE INDEX <name> IF NOT EXISTS FOR (n:`Label`) ON (n.`f1`, n.`f2`, ...)``.

    Neo4j requires named indexes; ``IF NOT EXISTS`` makes setup idempotent.
    """
    if not fields:
        raise ValueError("build_node_index_create requires at least one field")
    field_list = ", ".join(f"n.{_quote(f)}" for f in fields)
    return (
        f"CREATE INDEX {_quote(name)} IF NOT EXISTS "
        f"FOR (n:{_quote(label)}) ON ({field_list})"
    )


def build_node_index_drop(name: str) -> str:
    """``DROP INDEX <name> IF EXISTS``.

    Unlike FalkorDB's by-(label, field) drop, Neo4j drops indexes by name
    regardless of kind (node or relationship).
    """
    return f"DROP INDEX {_quote(name)} IF EXISTS"


def build_relationship_index_create(
    name: str,

View on GitHub (pinned to e84aa99b32)

Solutions

  1. Pass at least one field to index (e.g. ["id"] or the properties you query on)
  2. Skip calling build_node_index_create entirely when no fields are configured instead of calling it with an empty list
  3. Validate the index config at load time: reject index entries with no fields

Example fix

// before
build_node_index_create(name="person_email_idx", label="Person", fields=[])
// after
build_node_index_create(name="person_email_idx", label="Person", fields=["email"])
Defensive patterns

Strategy: validation

Validate before calling

if not fields:
    raise ValueError(f"index {name!r} configured with no fields; skip creation")
ddl = build_node_index_create(name=name, label=label, fields=fields)

Type guard

def indexable(fields) -> bool:
    return isinstance(fields, (list, tuple)) and len(fields) > 0

Try / catch

try:
    ddl = build_node_index_create(name, label, fields)
except ValueError as e:
    if "requires at least one field" in str(e):
        logger.warning("skipping index %r: no fields configured", name)
    else:
        raise

Prevention

When it happens

Trigger: Calling build_node_index_create(name=..., label=..., fields=[]) — no property fields supplied for the index.

Common situations: Index list built from config where the fields key was omitted/empty; code that conditionally adds fields and ends up with none; copying an index helper call without fields.

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


AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08). Data as JSON: /api/errors/16ce5b09691108ab. Report an issue: GitHub.