GitHub Issue: awslabs/graphrag-toolkit
Title
Bug: VersionManager generates invalid Cypher WHERE () AND ... on Neptune Database
Labels
bug
Body
Description
When using LexicalGraphIndex.extract_and_build(nodes, enable_versioning=True) with Neptune Database, the VersionManager._get_existing_source_nodes() method generates syntactically invalid Cypher that Neptune rejects.
Error
MalformedQueryException: Invalid input 'A': expected whitespace, comment
or a relationship pattern (line 4, column 18 (offset: 127))
[query_ref: e809b/*, query: // find source nodes to be versioned, parameters: **REDACTED**]
Root Cause
In version_manager.py, when other_filter_criteria is an empty dict (which occurs when nodes don't yet have nested source.metadata structure during the first build phase):
to_metadata_filter({}) creates MetadataFilters(filters=[])
parse_metadata_filters_recursive(MetadataFilters(filters=[])) joins an empty list and returns "()" (empty parentheses)
- The guard
if not where_clauses: return [] at line 70 does NOT catch this because "()" is a truthy 2-character string
- The generated query becomes:
WHERE () AND coalesce(source.__aws__versioning__id_fields__, ...) = $param
- Neptune rejects
WHERE () AND ... as syntactically invalid
Relevant code in graph_utils.py:parse_metadata_filters_recursive:
condition = f' {metadata_filters.condition.value.upper()} '
return f"({condition.join(filter_strs)})" # Returns "()" when filter_strs is []
Confirmed by Direct Neptune Testing
Ran isolated query tests against Neptune Database 1.4.7.0:
| Test |
Query Pattern |
Result |
| Map literal in RETURN |
RETURN {id: id(n)} AS result |
✅ Works |
__aws__ property names |
t.__aws__versioning__id_fields__ |
✅ Works |
| coalesce on versioning properties |
coalesce(t.__aws__versioning__valid_from__, -1) |
✅ Works |
| WHERE () AND filter |
WHERE () AND id(n) IS NOT NULL |
❌ MalformedQueryException |
| Full versioning query (properly formed WHERE) |
Complete pattern |
✅ Works |
All Cypher features used by the versioning system work on Neptune. The ONLY issue is the empty WHERE () clause.
Proposed Fix
Either:
Option A — Fix the guard in version_manager.py:70:
if not where_clauses or where_clauses.strip() in ('', '()'):
return []
Option B — Fix parse_metadata_filters_recursive in graph_utils.py to return '' for empty filter lists:
if not filter_strs:
return ''
Reproduction Steps
- Create TextNodes with flat metadata (e.g.,
{"page_id": "123", "space_key": "SD"})
- Call
add_versioning_info(metadata, id_fields=["page_id", "space_key"])
- Call
LexicalGraphIndex.extract_and_build(nodes, enable_versioning=True) against Neptune Database
- The extraction phase restructures metadata, but during certain code paths (first-time ingest, partial extraction), the
source.metadata dict lookup returns empty
- VersionManager generates invalid
WHERE () AND ... query
Environment
- Neptune Database: 1.4.7.0 (latest, Serverless)
- graphrag-lexical-graph: 3.18.6
- OpenSearch Serverless (AOSS)
- Region: us-east-1
Workaround
Disable versioning (enable_versioning=False). First-time ingest works correctly. For re-ingestion, call delete_sources() before re-ingesting.
GitHub Issue: awslabs/graphrag-toolkit
Title
Bug: VersionManager generates invalid Cypher
WHERE () AND ...on Neptune DatabaseLabels
bug
Body
Description
When using
LexicalGraphIndex.extract_and_build(nodes, enable_versioning=True)with Neptune Database, theVersionManager._get_existing_source_nodes()method generates syntactically invalid Cypher that Neptune rejects.Error
Root Cause
In
version_manager.py, whenother_filter_criteriais an empty dict (which occurs when nodes don't yet have nestedsource.metadatastructure during the first build phase):to_metadata_filter({})createsMetadataFilters(filters=[])parse_metadata_filters_recursive(MetadataFilters(filters=[]))joins an empty list and returns"()"(empty parentheses)if not where_clauses: return []at line 70 does NOT catch this because"()"is a truthy 2-character stringWHERE () AND coalesce(source.__aws__versioning__id_fields__, ...) = $paramWHERE () AND ...as syntactically invalidRelevant code in
graph_utils.py:parse_metadata_filters_recursive:Confirmed by Direct Neptune Testing
Ran isolated query tests against Neptune Database 1.4.7.0:
RETURN {id: id(n)} AS result__aws__property namest.__aws__versioning__id_fields__coalesce(t.__aws__versioning__valid_from__, -1)WHERE () AND id(n) IS NOT NULLAll Cypher features used by the versioning system work on Neptune. The ONLY issue is the empty
WHERE ()clause.Proposed Fix
Either:
Option A — Fix the guard in
version_manager.py:70:Option B — Fix
parse_metadata_filters_recursiveingraph_utils.pyto return''for empty filter lists:Reproduction Steps
{"page_id": "123", "space_key": "SD"})add_versioning_info(metadata, id_fields=["page_id", "space_key"])LexicalGraphIndex.extract_and_build(nodes, enable_versioning=True)against Neptune Databasesource.metadatadict lookup returns emptyWHERE () AND ...queryEnvironment
Workaround
Disable versioning (
enable_versioning=False). First-time ingest works correctly. For re-ingestion, calldelete_sources()before re-ingesting.