bytedance/deer-flow · error · MemoryStorageError
Failed to update global memory summaries
Error message
Failed to update global memory summaries
What it means
update_summaries() does load -> merge -> save(document, expected_revision) and raises MemoryStorageError when save() returns False. save() returns False on optimistic-concurrency failure (revision mismatch) or other non-exception commit rejections, meaning another writer changed the global memory document between the load and the save. Summaries are always user-global, never agent-specific, so the contention is on the user-level file.
Source
Thrown at backend/packages/harness/deerflow/agents/memory/backends/deermem/deermem/core/storage.py:1379
agent_name: str | None = None,
) -> dict[str, Any]:
document = self.load(agent_name, user_id=user_id)
return {"user": copy.deepcopy(document.get("user", {})), "history": copy.deepcopy(document.get("history", {})), "revision": document.get("revision", 0)}
def update_summaries(
self,
summaries: dict[str, Any],
*,
user_id: str | None = None,
agent_name: str | None = None,
expected_revision: int | None = None,
) -> dict[str, Any]:
# Summaries are always user-global, never agent-specific.
document = self.load(user_id=user_id)
document.update({key: copy.deepcopy(value) for key, value in summaries.items() if key in {"user", "history"}})
expected = int(document.get("revision") or 0) if expected_revision is None else expected_revision
if not self.save(document, user_id=user_id, expected_revision=expected):
raise MemoryStorageError("Failed to update global memory summaries")
return self.reload(user_id=user_id)
def notify_fact_upsert(self, fact: dict[str, Any], *, path: str = "") -> bool:
if self._retrieval is None:
return False
scope = fact.get("scope") if isinstance(fact.get("scope"), dict) else {}
self._retrieval.upsert(copy.deepcopy(fact), scope=copy.deepcopy(scope), path=path)
return True
def notify_fact_remove(self, fact_id: str, *, scope: dict[str, str | None]) -> bool:
if self._retrieval is None:
return False
self._retrieval.remove(fact_id, scope=copy.deepcopy(scope))
return True
def search_facts(
self,
query: str,View on GitHub (pinned to 1dd6ba1acb)
Solutions
- Retry the whole operation: catch MemoryStorageError, reload via storage.reload(user_id=...), re-apply the summary merge, save again (bounded attempts).
- Serialize summary updates per user_id with a lock in your service layer if retries are undesirable.
- Update summaries through a single owner (one coordinator) instead of many concurrent writers.
Example fix
# before
storage.update_summaries({"user": summary}, user_id=user_id)
# after
for attempt in range(3):
try:
storage.update_summaries({"user": summary}, user_id=user_id)
break
except MemoryStorageError:
if attempt == 2:
raise
time.sleep(0.1 * (attempt + 1)) Defensive patterns
Strategy: retry
Try / catch
last_exc = None
for attempt in range(3):
try:
storage.update_summaries(summaries, user_id=user_id)
break
except MemoryStorageError as exc:
last_exc = exc
storage.reload(user_id=user_id) # refresh revision before retry
else:
raise last_exc Prevention
- Serialize per-user summary updates behind a lock if contention is frequent.
- Keep the load-merge-save window short; do expensive LLM work before loading.
- Route all summary writes for a user through a single coordinator component.
When it happens
Trigger: Two threads/processes updating user summaries concurrently (e.g. two agents finishing turns for the same user at once); calling update_summaries repeatedly in a loop without reloading between attempts; passing an expected_revision that is already stale.
Common situations: Multi-agent workflows sharing one user_id; a memory updater racing with a fact save that also bumps the document revision; long-running processes holding an old revision across other writes.
Related errors
- Failed to save memory data after creating fact
- Failed to save memory data after deleting fact '{fact_id}'
- Failed to save memory data after updating fact '{fact_id}'
- Missing or empty 'messages' key in {path}
- chat prompt template not found: {name} (searched: {searched}
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/c657b1bce2b7bc08.
Report an issue: GitHub.