Skip to content

fix: preserve relationship direction in get_by_node_uuid and BFS edge search#1663

Open
6or7 wants to merge 2 commits into
getzep:mainfrom
6or7:fix/edge-direction-preservation
Open

fix: preserve relationship direction in get_by_node_uuid and BFS edge search#1663
6or7 wants to merge 2 commits into
getzep:mainfrom
6or7:fix/edge-direction-preservation

Conversation

@6or7

@6or7 6or7 commented Jul 17, 2026

Copy link
Copy Markdown

Summary

Fixes #1662

get_entity_edge_return_query now reads source_node_uuid/target_node_uuid from the relationship itself via
Cypher's startNode(e)/endNode(e) for NEO4J/FALKORDB/NEPTUNE, instead of from the n/m MATCH variables.

This fixes direction reversals in:

  • EntityEdge.get_by_node_uuid — when the queried node is the relationship's target
  • edge_bfs_search (Neo4j/FalkorDB/search_utils) — same class of bug for undirected MATCH

KUZU is unchanged: its e is a RelatesToNode_ intermediate node, not a relationship, so startNode/endNode don't
apply. KUZU's MATCH is always directed, so n/m already reflect the true source/target.

Root cause

For undirected MATCH like MATCH (n {uuid: $node_uuid})-[e]-(m), Cypher binds the queried node to n on every row.
The old RETURN n.uuid AS source_node_uuid, m.uuid AS target_node_uuid therefore reported the queried node as source
regardless of the stored relationship direction. See #1662 for full analysis.

Changes

  • graphiti_core/models/edges/edge_db_queries.py: switch NEO4J/FALKORDB/NEPTUNE branches of
    get_entity_edge_return_query to startNode(e)/endNode(e). KUZU branch unchanged with an explanatory comment.
  • tests/test_edge_db_queries.py: new unit tests covering the return shape per provider.
  • tests/test_edge_int.py: regression assertion — get_by_node_uuid(target_uuid) must preserve source=A, target=B.

No call sites needed to change — the fix lives entirely in the return-query builder.

Backward compatibility

No data migration required. startNode(e)/endNode(e) reads immutable relationship metadata, so historical data reads
correctly without any backfill.

Out of scope

KUZU's get_by_node_uuid only matches outgoing edges due to its directed MATCH pattern. Fixing this requires storing
source_uuid/target_uuid on RelatesToNode_ and a data backfill — left for a follow-up PR.

@zep-cla-assistant

zep-cla-assistant Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

… search

Switch get_entity_edge_return_query to use startNode(e)/endNode(e) for
NEO4J/FALKORDB/NEPTUNE so source/target reflect the stored relationship
direction regardless of MATCH directionality. Fixes direction reversal
in EntityEdge.get_by_node_uuid and edge_bfs_search when the queried
node is the relationship target.

KUZU is unchanged: its 'e' is a RelatesToNode_ intermediate node, not
a relationship, and its MATCH is already directed.

Adds unit tests for the return-query builder and a regression assertion
in test_entity_edge for the target-side get_by_node_uuid case.

Fixes getzep#1662
@6or7
6or7 force-pushed the fix/edge-direction-preservation branch from 202b1a3 to e437bb6 Compare July 17, 2026 07:57
@6or7

6or7 commented Jul 17, 2026

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

zep-cla-assistant Bot added a commit that referenced this pull request Jul 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] : EntityEdge.get_by_node_uuid returns swapped source/target when queried from the target side

1 participant