Bug Description
When a statement violates a uniqueness constraint, Neo4j reports Neo.ClientError.Schema.ConstraintValidationFailed. NornicDB reports a different code on every path:
- Bolt auto-commit:
Neo.ClientError.Statement.SyntaxError. The message is failed to create node: Constraint violation (UNIQUE on U.[k]): Node with k=1 already exists in batch.
- Bolt managed explicit transaction:
Neo.ClientError.Transaction.TransactionCommitFailed. The server also closes the Bolt connection after the failed COMMIT (the driver logs Failed to read from defunct connection … OSError('No data')). Neo4j keeps the connection open and returns the failure.
- HTTP
/tx/commit: Neo.ClientError.Statement.SyntaxError.
Consequence
Severity: wrong error class + dropped connection.
- Clients that handle a duplicate key by catching
ConstraintValidationFailed (upsert-on-conflict, "already exists" messages, idempotent retries) don't recognise it. A duplicate reported as SyntaxError looks like a bug in the query.
- A client that treats
TransactionCommitFailed as transient retries a write that will always fail.
- The closed connection forces the driver to discard it and reconnect after every violation inside a transaction.
Steps to Reproduce
Empty database:
CREATE CONSTRAINT u_k FOR (u:U) REQUIRE u.k IS UNIQUE
CREATE (:U {k: 5})
then each of these, via driver auto-commit, managed explicit transaction (session.execute_write) and HTTP /tx/commit:
CREATE (:U {k: 1}), (:U {k: 1})
CREATE (:U {k: 1})-[:R]->(:U {k: 1})
CREATE (:U {k: 2})-[:R]->(:T), (:U {k: 2})
CREATE (:T)-[:R]->(:T), (:U {k: 5})
Expected Behavior
Neo4j 5.26.30, on every path: Neo.ClientError.Schema.ConstraintValidationFailed, nothing written, and the connection stays usable.
Actual Behavior
NornicDB main 2d2d790: the codes listed above, and one closed Bolt connection per violating statement in a managed transaction. (On main, auto-commit and HTTP also keep part of the statement's nodes. That part is fixed by the #628 PR; the error codes and the closed connection are not.)
Environment
- NornicDB Version: main at 2d2d790
- Reference:
neo4j:5.26.30-community (pinned in scripts/cypher-tck/run-differential.sh), neo4j Python driver 5.28.1 and HTTP /tx/commit
- OS: Linux container on Docker Desktop / WSL2
- Architecture: AMD64
- Build:
-tags "noui,nolocalllm"
Related
Checklist
🤖 Generated with Claude Code
Bug Description
When a statement violates a uniqueness constraint, Neo4j reports
Neo.ClientError.Schema.ConstraintValidationFailed. NornicDB reports a different code on every path:Neo.ClientError.Statement.SyntaxError. The message isfailed to create node: Constraint violation (UNIQUE on U.[k]): Node with k=1 already exists in batch.Neo.ClientError.Transaction.TransactionCommitFailed. The server also closes the Bolt connection after the failed COMMIT (the driver logsFailed to read from defunct connection … OSError('No data')). Neo4j keeps the connection open and returns the failure./tx/commit:Neo.ClientError.Statement.SyntaxError.Consequence
Severity: wrong error class + dropped connection.
ConstraintValidationFailed(upsert-on-conflict, "already exists" messages, idempotent retries) don't recognise it. A duplicate reported asSyntaxErrorlooks like a bug in the query.TransactionCommitFailedas transient retries a write that will always fail.Steps to Reproduce
Empty database:
then each of these, via driver auto-commit, managed explicit transaction (
session.execute_write) and HTTP/tx/commit:Expected Behavior
Neo4j 5.26.30, on every path:
Neo.ClientError.Schema.ConstraintValidationFailed, nothing written, and the connection stays usable.Actual Behavior
NornicDB main 2d2d790: the codes listed above, and one closed Bolt connection per violating statement in a managed transaction. (On main, auto-commit and HTTP also keep part of the statement's nodes. That part is fixed by the #628 PR; the error codes and the closed connection are not.)
Environment
neo4j:5.26.30-community(pinned inscripts/cypher-tck/run-differential.sh), neo4j Python driver 5.28.1 and HTTP/tx/commit-tags "noui,nolocalllm"Related
/tx/commitreports every error as SyntaxError.Checklist
🤖 Generated with Claude Code