headroomlabs-ai/headroom · error · ValueError

Memory not found: {memory_id}

Error message

Memory not found: {memory_id}

What it means

ValueError raised by Mem0SystemAdapter.update_memory() when client.get(memory_id) returns falsy data (None, {}, empty). Note the preceding code swallows the original exception and sets existing_data = None, so this error also masks real backend failures — a Qdrant outage during the get() looks identical to a missing memory.

Source

Thrown at headroom/memory/backends/mem0_system_adapter.py:256

            reason: Reason for the update (for audit trail).
            user_id: User ID for validation (optional).

        Returns:
            The updated Memory object.

        Raises:
            ValueError: If memory not found.
        """
        # Get the existing memory using Mem0 client directly
        client = await self._backend._ensure_client()

        try:
            existing_data = await asyncio.to_thread(client.get, memory_id=memory_id)
        except Exception:
            existing_data = None

        if not existing_data:
            raise ValueError(f"Memory not found: {memory_id}")

        # Extract user_id from existing data
        existing_user_id = existing_data.get("user_id", "")

        # Validate user if provided
        if user_id and existing_user_id and existing_user_id != user_id:
            raise ValueError("Cannot update memories belonging to other users")

        # Build update metadata
        now = _utcnow()
        update_metadata: dict[str, Any] = {}
        if reason:
            update_metadata["update_reason"] = reason
            update_metadata["updated_at"] = now.isoformat()

        # Update via Mem0
        try:
            await asyncio.to_thread(

View on GitHub (pinned to 322425c43b)

Solutions

  1. Confirm the id exists in the same environment: call client.get(memory_id) or search by id directly
  2. If the store was wiped, re-create the memory with save() instead of update_memory()
  3. If you suspect backend issues, health-check Qdrant/mem0 — the get() exception is swallowed, so 'not found' may actually mean 'get failed'
  4. Log memory ids at save time so updates always reference known-good ids

Example fix

# before
await adapter.update_memory('mem-123', 'new text')  # ValueError: Memory not found: mem-123

# after
existing = await asyncio.to_thread(client.get, memory_id='mem-123')
if not existing:
    await system.save('new text', user_id='u1')  # re-create instead of update
else:
    await adapter.update_memory('mem-123', 'new text')
Defensive patterns

Strategy: validation

Validate before calling

client = await adapter._backend._ensure_client()
existing = await asyncio.to_thread(client.get, memory_id=memory_id)
if not existing:
    raise KeyError(memory_id)  # clearer signal than late ValueError
# safe to update now

Try / catch

try:
    await adapter.update_memory(memory_id, new_content, user_id=user_id)
except ValueError as e:
    if str(e).startswith('Memory not found'):
        # re-create instead of update
        await system.save(new_content, user_id=user_id)
    else:
        raise

Prevention

When it happens

Trigger: Updating a memory_id that was deleted, never existed, or whose collection was recreated; also fires when asyncio.to_thread(client.get, ...) raises any Exception (connection error, auth error) because the except block converts it to None.

Common situations: Holding ids across application restarts after the mem0 store was reset; wrong environment pointed at (dev vs prod mem0); transient backend errors misdiagnosed as 'not found'.

Related errors


AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15). Data as JSON: /api/errors/da377a13e7935275. Report an issue: GitHub.