Skip to content

fix(neo4j): cascade delete vectors from Qdrant when deleting memory nodes#1862

Open
AYin-Z wants to merge 7 commits into
MemTensor:dev-20260604-v2.0.19from
AYin-Z:fix/qdrant-cascade-delete
Open

fix(neo4j): cascade delete vectors from Qdrant when deleting memory nodes#1862
AYin-Z wants to merge 7 commits into
MemTensor:dev-20260604-v2.0.19from
AYin-Z:fix/qdrant-cascade-delete

Conversation

@AYin-Z

@AYin-Z AYin-Z commented Jun 2, 2026

Copy link
Copy Markdown

Description

delete_node_by_prams() only ran DETACH DELETE on Neo4j, leaving orphan vectors behind in Qdrant. Every memory deletion via the API created a leaked vector in Qdrant with no corresponding Neo4j node.

Root Cause

The write path (add_node / add_nodes_batch) is symmetric — it writes to both Neo4j and Qdrant in the same method. But the delete path only touched Neo4j:

# Before: count then delete Neo4j only
count_query = f"MATCH (n:Memory) WHERE ... RETURN count(n) AS node_count"
...
session.run("MATCH (n:Memory) WHERE ... DETACH DELETE n", **params)
# ← No vec_db.delete() call

Note that clear() and the newer delete_node_by_mem_cube_id() both correctly call vec_db.delete() — this was simply an omission in delete_node_by_prams.

Fix

  1. Replace count_query with an ids_query that collects node IDs
  2. Delete from Neo4j (same as before)
  3. Call self.vec_db.delete(deleted_ids) after successful Neo4j deletion

Verification

  • BaseVecDB.delete(ids) is an abstract method with working implementations in both QdrantVecDB and MilvusVecDB
  • self.vec_db is initialized in the constructor and used elsewhere in the same class
  • The fix gracefully falls back with a warning log if Qdrant cleanup fails

hijzy and others added 7 commits May 25, 2026 15:02
## Summary
- add an OpenClaw runtime lock to block duplicate plugin instances
before tools/hooks register
- fail startup on viewer port conflicts and clean up partial runtime
state
- keep lightweight local memories searchable/listable without an LLM
final filter, while preserving full-mode self-evolution boundaries
- cover runtime locking, duplicate startup, lightweight retrieval,
delayed agent_end recovery, and partial migration behavior

## Tests
- npm test -- --run tests/unit
- npm run lint
- npm run build
- git diff --check --cached
MemTensor#1807)

Automated PR from mem-agent-0520-niu to mem-agent-0520.
## Description

Please include a summary of the change, the problem it solves, the
implementation approach, and relevant context. List any dependencies
required for this change.

Related Issue (Required):  Fixes #issue_number

## Type of change

Please delete options that are not relevant.

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] Refactor (does not change functionality, e.g. code style
improvements, linting)
- [ ] Documentation update

## How Has This Been Tested?

Please describe the tests that you ran to verify your changes. Provide
instructions so we can reproduce. Please also list any relevant details
for your test configuration

- [ ] Unit Test
- [ ] Test Script Or Test Steps (please provide)
- [ ] Pipeline Automated API Test (please provide)

## Checklist

- [ ] I have performed a self-review of my own code | 我已自行检查了自己的代码
- [ ] I have commented my code in hard-to-understand areas |
我已在难以理解的地方对代码进行了注释
- [ ] I have added tests that prove my fix is effective or that my
feature works | 我已添加测试以证明我的修复有效或功能正常
- [ ] I have created related documentation issue/PR in
[MemOS-Docs](https://github.com/MemTensor/MemOS-Docs) (if applicable) |
我已在 [MemOS-Docs](https://github.com/MemTensor/MemOS-Docs) 中创建了相关的文档
issue/PR(如果适用)
- [ ] I have linked the issue to this PR (if applicable) | 我已将 issue
链接到此 PR(如果适用)
- [ ] I have mentioned the person who will review this PR | 我已提及将审查此 PR
的人

## Reviewer Checklist
- [ ] closes #xxxx (Replace xxxx with the GitHub issue number)
- [ ] Made sure Checks passed
- [ ] Tests have been provided
…odes

delete_node_by_prams only ran DETACH DELETE on Neo4j, leaving orphan
vectors in Qdrant. Since add_node/add_nodes_batch write to both
stores symmetrically, the delete path should also clean up Qdrant.

This collects matching node IDs before Neo4j deletion, then calls
vec_db.delete() with the collected IDs. Falls back gracefully with
a warning if Qdrant cleanup fails.
@Memtensor-AI Memtensor-AI changed the base branch from main to dev-20260604-v2.0.19 June 10, 2026 15:43
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.

3 participants