{"record":{"id":"da377a13e7935275","repo":"headroomlabs-ai/headroom","slug":"memory-not-found-memory-id-da377a","errorCode":null,"errorMessage":"Memory not found: {memory_id}","messagePattern":"Memory not found: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"headroom/memory/backends/mem0_system_adapter.py","lineNumber":256,"sourceCode":"            reason: Reason for the update (for audit trail).\n            user_id: User ID for validation (optional).\n\n        Returns:\n            The updated Memory object.\n\n        Raises:\n            ValueError: If memory not found.\n        \"\"\"\n        # Get the existing memory using Mem0 client directly\n        client = await self._backend._ensure_client()\n\n        try:\n            existing_data = await asyncio.to_thread(client.get, memory_id=memory_id)\n        except Exception:\n            existing_data = None\n\n        if not existing_data:\n            raise ValueError(f\"Memory not found: {memory_id}\")\n\n        # Extract user_id from existing data\n        existing_user_id = existing_data.get(\"user_id\", \"\")\n\n        # Validate user if provided\n        if user_id and existing_user_id and existing_user_id != user_id:\n            raise ValueError(\"Cannot update memories belonging to other users\")\n\n        # Build update metadata\n        now = _utcnow()\n        update_metadata: dict[str, Any] = {}\n        if reason:\n            update_metadata[\"update_reason\"] = reason\n            update_metadata[\"updated_at\"] = now.isoformat()\n\n        # Update via Mem0\n        try:\n            await asyncio.to_thread(","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/headroom/memory/backends/mem0_system_adapter.py#L238-L274","documentation":"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.","triggerScenarios":"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.","commonSituations":"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'.","solutions":["Confirm the id exists in the same environment: call client.get(memory_id) or search by id directly","If the store was wiped, re-create the memory with save() instead of update_memory()","If you suspect backend issues, health-check Qdrant/mem0 — the get() exception is swallowed, so 'not found' may actually mean 'get failed'","Log memory ids at save time so updates always reference known-good ids"],"exampleFix":"# before\nawait adapter.update_memory('mem-123', 'new text')  # ValueError: Memory not found: mem-123\n\n# after\nexisting = await asyncio.to_thread(client.get, memory_id='mem-123')\nif not existing:\n    await system.save('new text', user_id='u1')  # re-create instead of update\nelse:\n    await adapter.update_memory('mem-123', 'new text')","handlingStrategy":"validation","validationCode":"client = await adapter._backend._ensure_client()\nexisting = await asyncio.to_thread(client.get, memory_id=memory_id)\nif not existing:\n    raise KeyError(memory_id)  # clearer signal than late ValueError\n# safe to update now","typeGuard":null,"tryCatchPattern":"try:\n    await adapter.update_memory(memory_id, new_content, user_id=user_id)\nexcept ValueError as e:\n    if str(e).startswith('Memory not found'):\n        # re-create instead of update\n        await system.save(new_content, user_id=user_id)\n    else:\n        raise","preventionTips":["Remember get() exceptions are swallowed — 'not found' can mask backend outages, so health-check when in doubt","Never persist memory ids across store resets","Log ids at creation time for traceability"],"tags":["python","mem0","not-found","update","valueerror","memory-backend"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}