From d2ff83cf7246d78d9fb22aa2d04c19b7bf231870 Mon Sep 17 00:00:00 2001 From: Hrushikesh Yadav <136978914+HrushiYadav@users.noreply.github.com> Date: Thu, 25 Jun 2026 16:13:44 +0530 Subject: [PATCH] fix(redis): use .get() for hash/created_at in insert() to handle entity payloads (#5709) --- mem0/vector_stores/redis.py | 20 ++++++++----- tests/vector_stores/test_redis.py | 48 +++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/mem0/vector_stores/redis.py b/mem0/vector_stores/redis.py index 32a8941bd..8c982aace 100644 --- a/mem0/vector_stores/redis.py +++ b/mem0/vector_stores/redis.py @@ -124,11 +124,13 @@ class RedisDB(VectorStoreBase): data = [] for vector, payload, id in zip(vectors, payloads, ids): # Start with required fields + created_at_str = payload.get("created_at") + created_at_ts = int(datetime.fromisoformat(created_at_str).timestamp()) if created_at_str else 0 entry = { "memory_id": id, - "hash": payload["hash"], - "memory": payload["data"], - "created_at": int(datetime.fromisoformat(payload["created_at"]).timestamp()), + "hash": payload.get("hash", ""), + "memory": payload.get("data", ""), + "created_at": created_at_ts, "embedding": np.array(vector, dtype=np.float32).tobytes(), } @@ -244,12 +246,16 @@ class RedisDB(VectorStoreBase): self.index.drop_keys(f"{self.schema['index']['prefix']}:{vector_id}") def update(self, vector_id=None, vector=None, payload=None): + created_at_str = payload.get("created_at") + created_at_ts = int(datetime.fromisoformat(created_at_str).timestamp()) if created_at_str else 0 + updated_at_str = payload.get("updated_at") + updated_at_ts = int(datetime.fromisoformat(updated_at_str).timestamp()) if updated_at_str else 0 data = { "memory_id": vector_id, - "hash": payload["hash"], - "memory": payload["data"], - "created_at": int(datetime.fromisoformat(payload["created_at"]).timestamp()), - "updated_at": int(datetime.fromisoformat(payload["updated_at"]).timestamp()), + "hash": payload.get("hash", ""), + "memory": payload.get("data", ""), + "created_at": created_at_ts, + "updated_at": updated_at_ts, } # Only update embedding if vector is provided diff --git a/tests/vector_stores/test_redis.py b/tests/vector_stores/test_redis.py index 13cae0edb..03484cd72 100644 --- a/tests/vector_stores/test_redis.py +++ b/tests/vector_stores/test_redis.py @@ -180,3 +180,51 @@ def test_get_returns_none_for_missing_id(): assert db.get("missing_id") is None mock_index.fetch.assert_called_once_with("missing_id") + + +def test_insert_entity_payload_without_hash_and_created_at(): + """insert() must not crash on entity payloads that lack hash/created_at.""" + db, mock_index = _make_redis_db() + + entity_payload = { + "data": "OpenAI", + "entity_type": "organization", + "linked_memory_ids": ["mem-1"], + "user_id": "test_user", + } + + db.insert( + vectors=[[0.1, 0.2, 0.3]], + payloads=[entity_payload], + ids=["entity-1"], + ) + + mock_index.load.assert_called_once() + data = mock_index.load.call_args[0][0] + assert data[0]["memory_id"] == "entity-1" + assert data[0]["memory"] == "OpenAI" + assert data[0]["hash"] == "" + assert data[0]["created_at"] == 0 + + +def test_update_entity_payload_without_hash_and_timestamps(): + """update() must not crash on entity payloads that lack hash/created_at/updated_at.""" + db, mock_index = _make_redis_db() + + entity_payload = { + "data": "OpenAI", + "entity_type": "organization", + "linked_memory_ids": ["mem-1"], + "user_id": "test_user", + } + + db.update(vector_id="entity-1", vector=[0.1, 0.2, 0.3], payload=entity_payload) + + mock_index.load.assert_called_once() + call_kwargs = mock_index.load.call_args + data_dict = call_kwargs[1]["data"][0] if "data" in call_kwargs[1] else call_kwargs[0][0][0] + assert data_dict["memory_id"] == "entity-1" + assert data_dict["memory"] == "OpenAI" + assert data_dict["hash"] == "" + assert data_dict["created_at"] == 0 + assert data_dict["updated_at"] == 0