headroomlabs-ai/headroom · error · ValueError

Failed to update memory: {e}

Error message

Failed to update memory: {e}

What it means

A ValueError raised by DirectMem0Adapter.update_memory() when the underlying self._mem0_client.update(...) call (run via asyncio.to_thread) throws for any reason. The original exception is chained ('from e') but its message is embedded into this generic wrapper, so the root cause (bad memory id, connectivity, mem0 API change) must be read from the inner text.

Source

Thrown at headroom/memory/backends/direct_mem0.py:884

        Args:
            memory_id: ID of the memory to update.
            new_content: New content to replace existing.
            reason: Reason for the update.
            user_id: User ID for validation.

        Returns:
            Updated Memory object.
        """
        await self._ensure_initialized()

        try:
            await asyncio.to_thread(
                self._mem0_client.update,
                memory_id=memory_id,
                data=new_content,
            )
        except Exception as e:
            raise ValueError(f"Failed to update memory: {e}") from e

        return Memory(
            id=memory_id,
            content=new_content,
            user_id=user_id or "",
            importance=0.5,
            created_at=_utcnow(),
            valid_from=_utcnow(),
            metadata={"update_reason": reason} if reason else {},
        )

    async def delete_memory(
        self,
        memory_id: str,
        reason: str | None = None,
        user_id: str | None = None,
    ) -> bool:
        """Delete a memory.

View on GitHub (pinned to 322425c43b)

Solutions

  1. Read the '{e}' suffix of the message — it carries the real mem0 error and dictates the fix
  2. Verify the memory id exists first (search/get by id) before updating
  3. Check Qdrant/Neo4j service health (docker compose ps) if the inner error is a connection failure
  4. Pin compatible versions: reinstall 'headroom-ai[memory-stack]' so mem0 matches what the adapter expects

Example fix

# before
await adapter.update_memory('bad-id', 'new text')  # ValueError: Failed to update memory: ...

# after
mem = await adapter.get_memory('bad-id')  # confirm existence / get valid id
if mem:
    await adapter.update_memory(mem.id, 'new text')
Defensive patterns

Strategy: try-catch

Validate before calling

# confirm the target exists before updating
found = await adapter.get_memory(memory_id) if hasattr(adapter, 'get_memory') else None
if found is None:
    # avoid the wrapped failure: nothing to update
    raise KeyError(memory_id)

Try / catch

try:
    updated = await adapter.update_memory(memory_id, new_content)
except ValueError as e:
    # inner mem0 error is embedded in the message
    logger.error('update failed for %s: %s', memory_id, e)
    if 'not found' in str(e):
        await adapter.save(new_content, user_id=user_id)  # recreate path
    else:
        raise

Prevention

When it happens

Trigger: Calling update_memory(memory_id, new_content) where memory_id does not exist in the mem0/Qdrant store, Qdrant or the mem0 backend is unreachable, or the installed mem0 version renamed the 'update' kwargs.

Common situations: Stale memory_id kept after a store wipe or collection re-creation; Qdrant container down; mem0 upgraded to a version with an incompatible client API.

Related errors


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