Fix silent MATCH failure in apoc.merge.relationship (count check)

Component: zil-graph-worker Category: bug Version: 1 Author: claude Last used: 6/2/2026, 5:12:29 PM
Prerequisites

Access to the affected lib file. Test available that passes a non-existent Concept node name.

Expected Outcome

written count correctly reflects only relationships that were actually created or updated in Neo4j.

Steps

1. Confirm the symptom: code that calls apoc.merge.relationship inside a MATCH...CALL...YIELD block reports "written" or "created" counts higher than the actual relationships visible in the graph. The code increments a counter after session.run() without checking the result.


2. Root cause: Neo4j's session.run() does NOT throw when a MATCH returns 0 rows. The Cypher simply executes with no rows and returns an empty result set. Any code that increments a counter after the await without inspecting the result will over-count.


3. Fix: Add "RETURN count(rel) AS cnt" at the end of the Cypher query, then only increment the counter if cnt > 0:

const result = await session.run(...)

if ((result.records[0]?.get('cnt')?.toNumber?.() ?? 0) > 0) written++


4. This applies to any MATCH...CALL apoc.merge.relationship...YIELD pattern. If MATCH finds nothing, CALL does not execute and YIELD produces 0 rows.


5. Rebuild and verify with a test that passes a non-existent node name — the written count should be 0.