{"record":{"id":"db89f566e55df3b0","repo":"cocoindex-io/cocoindex","slug":"build-constraint-create-requires-at-least-one-fiel","errorCode":null,"errorMessage":"build_constraint_create requires at least one field","messagePattern":"build_constraint_create requires at least one field","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/cocoindex/connectors/neo4j/_cypher.py","lineNumber":224,"sourceCode":"    \"\"\"``DROP INDEX <name> IF EXISTS``.\n\n    Same DROP statement as for node indexes — Neo4j unifies the namespace.\n    \"\"\"\n    return f\"DROP INDEX {_quote(name)} IF EXISTS\"\n\n\ndef build_constraint_create(\n    name: str,\n    label: str,\n    fields: Sequence[str],\n) -> str:\n    \"\"\"``CREATE CONSTRAINT <name> IF NOT EXISTS FOR (n:`Label`) REQUIRE n.`f1` IS UNIQUE``.\n\n    For a single-field PK uses ``REQUIRE n.f IS UNIQUE``; for compound PKs\n    uses ``REQUIRE (n.f1, n.f2) IS NODE KEY`` (Neo4j 5 syntax).\n    \"\"\"\n    if not fields:\n        raise ValueError(\"build_constraint_create requires at least one field\")\n    if len(fields) == 1:\n        field_expr = f\"n.{_quote(fields[0])} IS UNIQUE\"\n    else:\n        field_list = \", \".join(f\"n.{_quote(f)}\" for f in fields)\n        field_expr = f\"({field_list}) IS NODE KEY\"\n    return (\n        f\"CREATE CONSTRAINT {_quote(name)} IF NOT EXISTS \"\n        f\"FOR (n:{_quote(label)}) REQUIRE {field_expr}\"\n    )\n\n\ndef build_constraint_drop(name: str) -> str:\n    \"\"\"``DROP CONSTRAINT <name> IF EXISTS``.\"\"\"\n    return f\"DROP CONSTRAINT {_quote(name)} IF EXISTS\"\n\n\ndef build_vector_index_create(\n    name: str,","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/cocoindex-io/cocoindex/blob/e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b/python/cocoindex/connectors/neo4j/_cypher.py#L206-L242","documentation":"This ValueError is raised by build_constraint_create when the fields sequence for a Neo4j node constraint (UNIQUE for single field, NODE KEY for compound) is empty. A constraint must reference at least one property; generating the REQUIRE clause with no fields would be invalid Cypher. The library validates before building the statement.","triggerScenarios":"Calling build_constraint_create(name, label, fields=[]) — e.g. passing an empty primary-key field list from config or schema introspection.","commonSituations":"A table/node schema whose primary key fields list is empty; a typo causing the fields list to be filtered down to nothing; wiring up constraint creation before the schema is populated.","solutions":["Pass at least one field name, e.g. ['id'] for a UNIQUE constraint or ['org_id','user_id'] for a NODE KEY.","Guard the call site: skip constraint creation if the fields list is empty.","Check where fields is constructed to ensure the schema's key columns are captured."],"exampleFix":"// before\nbuild_constraint_create(\"user_email_unique\", \"User\", [])\n// after\nbuild_constraint_create(\"user_email_unique\", \"User\", [\"email\"])","handlingStrategy":"validation","validationCode":"if not fields:\n    raise ValueError(\"constraint fields must contain at least one property\")\nbuild_constraint_create(name, label, fields)","typeGuard":null,"tryCatchPattern":"try:\n    stmt = build_constraint_create(name, label, fields)\nexcept ValueError as e:\n    logging.warning(\"skipping constraint %s: %s\", name, e)","preventionTips":["Validate the primary-key field list when loading schema config","Default to ['id'] when no explicit key fields are configured","Unit-test constraint building with empty-field cases"],"tags":["neo4j","cypher","validation","empty-argument"],"backgroundTag":"empty-required-field","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"}