Skip to content

fix(graph): soft-delete graph relationships instead of hard DELETE#4188

Merged
kartik-mem0 merged 4 commits intomem0ai:mainfrom
sxu75374:fix/graph-memory-soft-delete-4187
Mar 21, 2026
Merged

fix(graph): soft-delete graph relationships instead of hard DELETE#4188
kartik-mem0 merged 4 commits intomem0ai:mainfrom
sxu75374:fix/graph-memory-soft-delete-4187

Conversation

@sxu75374
Copy link
Copy Markdown
Contributor

@sxu75374 sxu75374 commented Mar 2, 2026

What this PR does

Replaces hard DELETE r in graph memory's conflict resolution with soft-delete (SET r.valid = false), aligning the implementation with the architecture described in the Mem0 paper (arXiv:2504.19413).

Fixes #4187

Changes

  • graph_memory.py: _delete_entities now uses SET r.valid = false instead of DELETE r
  • graph_memory.py: Search and get_all queries filter on WHERE r.valid IS NULL OR r.valid = true — backward compatible with existing edges that don't have the valid property
  • test_graph_memory_soft_delete.py: 8 tests covering Cypher generation, search filters, get_all filters, backward compat, and idempotency

Why

The current hard DELETE permanently removes graph edges, making temporal reasoning impossible. When importing historical data, conflict detection can corrupt current state by deleting newer edges and replacing them with older information.

Soft-delete preserves edge history and enables future temporal queries via include_historical parameter.

Backward Compatibility

Uses r.valid IS NULL OR r.valid = true so existing edges without the valid property continue to appear in queries. No migration needed.

Signed-off-by: sxu75374 imshuaixu@gmail.com

Replace hard DELETE in _delete_entities with SET r.valid = false to
enable temporal reasoning over historical graph state, aligning the
implementation with the paper's described architecture (arXiv:2504.19413).

- _delete_entities: SET r.valid = false, r.invalidated_at = datetime()
- _search_graph_db: filter WHERE r.valid IS NULL OR r.valid = true
- get_all: same filter for consistency
- delete_all: unchanged (explicit user action keeps DETACH DELETE)

The IS NULL check ensures backward compatibility with existing edges
that lack the valid property.

Note: For large graphs with frequent updates, consider adding a Neo4j
index on the valid property for relationship types that are frequently
queried: CREATE INDEX rel_valid FOR ()-[r:RELATIONSHIP]-() ON (r.valid)

Fixes mem0ai#4187

Signed-off-by: sxu75374 <imshuaixu@gmail.com>
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Mar 2, 2026

CLA assistant check
All committers have signed the CLA.

@kartik-mem0 kartik-mem0 merged commit 884e740 into mem0ai:main Mar 21, 2026
6 of 7 checks passed
jamebobob pushed a commit to jamebobob/mem0-vigil-recall that referenced this pull request Mar 29, 2026
…em0ai#4188)

Signed-off-by: sxu75374 <imshuaixu@gmail.com>
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
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.

Graph memory uses hard DELETE instead of soft-delete — breaks temporal reasoning described in paper

3 participants