From 929a5ea4be27e156558654b4995d15b808b20dac Mon Sep 17 00:00:00 2001 From: "glin1993@outlook.com" <> Date: Wed, 25 Feb 2026 16:03:22 +0800 Subject: [PATCH] =?UTF-8?q?fix(add=5Fhandler):=20fix=20add/update=20log=20?= =?UTF-8?q?judgment=20=E2=80=94=20scope=20by=20user=5Fname=20and=20exclude?= =?UTF-8?q?=20self-match?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add user_name=msg.mem_cube_id to get_by_metadata() to prevent cross-user key matching - Exclude mem_item.id from candidates to prevent the just-persisted node from always triggering the UPDATE path (self-match bug) - Wrap get_by_metadata() in try/except so Cypher parse errors (e.g. from special chars in key) are logged as warnings instead of silently swallowing the item as missing - Add null-safety check on original_mem_item before accessing .memory --- .../handlers/add_handler.py | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/memos/mem_scheduler/task_schedule_modules/handlers/add_handler.py b/src/memos/mem_scheduler/task_schedule_modules/handlers/add_handler.py index 63718fd92..a30119cf4 100644 --- a/src/memos/mem_scheduler/task_schedule_modules/handlers/add_handler.py +++ b/src/memos/mem_scheduler/task_schedule_modules/handlers/add_handler.py @@ -76,23 +76,37 @@ def log_add_messages(self, msg: ScheduleMessageItem): original_item_id = None if key and hasattr(mem_cube.text_mem, "graph_store"): - candidates = mem_cube.text_mem.graph_store.get_by_metadata( - [ - {"field": "key", "op": "=", "value": key}, - { - "field": "memory_type", - "op": "=", - "value": mem_item.metadata.memory_type, - }, - ] - ) + try: + candidates = mem_cube.text_mem.graph_store.get_by_metadata( + [ + {"field": "key", "op": "=", "value": key}, + { + "field": "memory_type", + "op": "=", + "value": mem_item.metadata.memory_type, + }, + ], + user_name=msg.mem_cube_id, + ) + except Exception as e: + logger.warning( + "get_by_metadata failed for memory_id=%s key=%s: %s", + memory_id, + key, + e, + ) + candidates = [] + # Exclude the current item itself — it was already persisted + # upstream by text_mem.add(), so it will always appear in the + # candidates and would cause every ADD to be mis-labelled as UPDATE. + candidates = [c for c in candidates if c != mem_item.id] if candidates: exists = True original_item_id = candidates[0] original_mem_item = mem_cube.text_mem.get( memory_id=original_item_id, user_name=msg.mem_cube_id ) - original_content = original_mem_item.memory + original_content = original_mem_item.memory if original_mem_item else None if exists: prepared_update_items_with_original.append(