Skip to content

Bug Report: actor_id metadata gets overwritten during memory UPDATE operations #4490

Description

@VictorECDSA

🐛 Describe the bug

Bug Report: actor_id metadata gets overwritten during memory UPDATE operations

Description

I believe I may have found a bug related to actor_id handling in multi-actor scenarios. When using metadata={"actor_id": ...} with shared user_id, the actor_id field appears to be overwritten when a different actor triggers an UPDATE event, which seems to break actor-level memory isolation and query filtering.

I'm not sure if this is the intended behavior, but I wanted to report it in case it's helpful.

Steps to Reproduce

from mem0 import Memory

m = Memory.from_config(config)

# Step 1: Actor A creates memory
result_a = m.add(
    [{"role": "user", "content": "I am player #1"}],
    user_id="team",
    metadata={"actor_id": "Alice"}
)
# ✓ Memory created with actor_id="Alice"

# Step 2: Actor B updates A's memory  
result_b = m.add(
    [{"role": "user", "content": "Player #1 is a good person"}],
    user_id="team",
    metadata={"actor_id": "Bob"}
)
# ❌ Memory updated but actor_id becomes "Bob"

# Step 3: Query by original creator
alice_memories = m.search(query="", user_id="team", filters={"actor_id": "Alice"})
print(f"Query Alice's memories: {len(alice_memories['results'])} found")
# Returns: 0 found

Expected Behavior

After Bob's UPDATE:

  • Memory content should be updated: "Player #1 is a good person"
  • actor_id should remain: "Alice" (original creator)
  • Query filters={"actor_id": "Alice"} should return 1 result

Actual Behavior

After Bob's UPDATE:

  • Memory content is updated correctly ✓
  • actor_id is overwritten to: "Bob"
  • Query filters={"actor_id": "Alice"} returns empty ❌

Output:

=== State AFTER Bob's UPDATE ===
  Event: UPDATE
  This actor_id: 'Bob'  ← Overwritten!

ISOLATION TEST:
  Query Alice's memories: 0 found
  ❌ BUG: Alice's memory lost!

Impact

  1. Cannot query by original creator after UPDATE
  2. Memory ownership tracking lost - can't identify who created the memory
  3. Actor isolation fails in shared user_id scenarios (e.g., team workspaces, multi-player games, collaborative agents)

Root Cause

In mem0/memory/main.py, the _update_memory() method (lines 1251-1252 for sync, 2347-2349 for async):

# Current implementation
if "actor_id" not in new_metadata and "actor_id" in existing_memory.payload:
    new_metadata["actor_id"] = existing_memory.payload["actor_id"]

Issue: The condition checks "actor_id" not in new_metadata, but new_metadata always contains the current actor's ID (passed from line 1668/1662 via metadata=deepcopy(metadata)), so preservation never happens.

Possible Solution (If This Is Indeed a Bug)

I've done some investigation and found that the issue might be in the condition check at lines 1251-1252 (sync) and 2347-2349 (async). Perhaps removing the condition check could help preserve the original actor_id:

# Suggested modification
if "actor_id" in existing_memory.payload:
    new_metadata["actor_id"] = existing_memory.payload["actor_id"]

This would treat actor_id as "memory owner" rather than "last updater". The history table (db.add_history()) already tracks all contributors, so update history wouldn't be lost.

However, I'm not familiar with the full design intentions, so this is just my humble suggestion. Please feel free to correct me if I'm misunderstanding something!

My Testing (For Reference)

I've tried to verify this potential fix using a monkey patch on my local setup:

Monkey Patch Test (Click to expand)
from mem0.memory.main import Memory as MemoryClass

def _patched_update_memory(self, memory_id, data, existing_embeddings, metadata=None):
    # ... (identical to original except:)
    
    # ===== FIX =====
    if "actor_id" in existing_memory.payload:
        new_metadata["actor_id"] = existing_memory.payload["actor_id"]
    # ===============
    
    # ... (rest unchanged)

MemoryClass._update_memory = _patched_update_memory

# Run same test...

Output (After Fix):

=== State AFTER Bob's UPDATE ===
  Event: UPDATE
  This actor_id: 'Alice'  ← Preserved!

ISOLATION TEST:
  Query Alice's memories: 1 found
  ✅ SUCCESS: Alice's memory preserved!

Environment

  • Mem0 version: v1.0.7
  • Python: 3.13
  • Vector Store: Qdrant (local)
  • OS: macOS

Additional Context

  • This affects both sync and async implementations of _update_memory()
  • The same issue applies to any custom metadata fields that should be preserved across updates
  • Current behavior is inconsistent with how user_id, agent_id, and run_id are preserved (lines 1245-1250)

Use Cases Affected

  • Multi-player games: Shared team memory with per-player contributions
  • Collaborative AI agents: Multiple agents updating shared knowledge base
  • Team workspaces: Tracking which team member created each memory
  • Multi-user chatbots: Preserving memory ownership in shared conversations

Request for Feedback

I would really appreciate it if the maintainers could take a look at this issue and let me know if:

  1. This is indeed a bug or if it's the intended behavior
  2. My understanding of the root cause is correct
  3. The suggested fix makes sense for the overall design

If this is confirmed as a bug and the proposed solution is acceptable, I would be honored to submit a Pull Request with the fix (including proper tests if needed). I've already prepared a draft PR and tested it locally with the monkey patch approach.

Of course, if there's a better way to handle this or if I'm missing something important, please feel free to guide me. I'm still learning about the codebase and would love any feedback!

Thank you so much for creating and maintaining this excellent library. It's been incredibly useful for my project! 🙏

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1-highBlocks significant use case, high demandbugSomething isn't workingsdk-pythonPython SDK specific

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions