From a65634c2e11963773756d0a7e1c9daed04ac06f7 Mon Sep 17 00:00:00 2001 From: supmo668 Date: Sun, 23 Nov 2025 19:21:55 -0800 Subject: [PATCH] fix: Handle EquivalentSchemaRuleAlreadyExists errors in Neo4j driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #1079 Neo4j 5.26+ throws EquivalentSchemaRuleAlreadyExists errors when creating indices in parallel, even with IF NOT EXISTS clause. This fix: - Catches neo4j.exceptions.ClientError exceptions - Checks for EquivalentSchemaRuleAlreadyExists error code - Logs the occurrence as info instead of error - Returns empty result to indicate success (index/constraint exists) This prevents the MCP server from crashing on startup when multiple CREATE INDEX IF NOT EXISTS queries run concurrently via semaphore_gather. The solution follows the same pattern already implemented in the FalkorDB driver for handling "already indexed" errors. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- graphiti_core/driver/neo4j_driver.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/graphiti_core/driver/neo4j_driver.py b/graphiti_core/driver/neo4j_driver.py index 4fa73f57..c75ed82e 100644 --- a/graphiti_core/driver/neo4j_driver.py +++ b/graphiti_core/driver/neo4j_driver.py @@ -18,6 +18,7 @@ import logging from collections.abc import Coroutine from typing import Any +import neo4j.exceptions from neo4j import AsyncGraphDatabase, EagerResult from typing_extensions import LiteralString @@ -70,6 +71,15 @@ class Neo4jDriver(GraphDriver): try: result = await self.client.execute_query(cypher_query_, parameters_=params, **kwargs) + except neo4j.exceptions.ClientError as e: + # Handle race condition when creating indices/constraints in parallel + # Neo4j 5.26+ may throw EquivalentSchemaRuleAlreadyExists even with IF NOT EXISTS + if 'EquivalentSchemaRuleAlreadyExists' in str(e): + logger.info(f'Index or constraint already exists, continuing: {cypher_query_}') + # Return empty result to indicate success (index exists) + return EagerResult([], None, None) # type: ignore + logger.error(f'Error executing Neo4j query: {e}\n{cypher_query_}\n{params}') + raise except Exception as e: logger.error(f'Error executing Neo4j query: {e}\n{cypher_query_}\n{params}') raise