bytedance/deer-flow · error · OSError
Failed to save memory data after updating fact '{fact_id}'
Error message
Failed to save memory data after updating fact '{fact_id}' What it means
The final legacy-path persistence step of update_memory_fact: after building updated_facts and confirming the target exists, _save_memory_to_file returns False and the update is discarded with this OSError. As with other legacy saves, False means a lost revision race or an I/O failure.
Source
Thrown at backend/packages/harness/deerflow/agents/memory/backends/deermem/deermem/core/updater.py:1092
updated_fact["confidence"] = _validate_confidence(confidence)
updated_facts.append(updated_fact)
else:
updated_facts.append(fact)
if not found:
raise KeyError(fact_id)
if getattr(type(self._storage), "apply_changes", None) is not MemoryStorage.apply_changes:
changed = next(fact for fact in updated_facts if fact.get("id") == fact_id)
self._storage.apply_changes(
{"upserts": [changed], "upsertRevisions": {fact_id: int(changed.get("revision") or 1)}},
agent_name=agent_name,
user_id=user_id,
expected_manifest_revision=int(memory_data.get("revision") or 0),
allow_manifest_rebase=True,
)
return self.get_memory_data(agent_name, user_id=user_id)
updated_memory["facts"] = updated_facts
if not self._save_memory_to_file(updated_memory, agent_name, user_id=user_id, expected_revision=int(memory_data.get("revision") or 0)):
raise OSError(f"Failed to save memory data after updating fact '{fact_id}'")
return updated_memory
def _build_signal_hints(self, signals: frozenset[str]) -> str:
"""Build optional prompt hints for the detected signal classes.
Each present signal contributes one instruction nudging the extraction
LLM toward the right category and confidence. The variable is still
rendered into the template's ``{correction_hint}`` slot (the name is
historical -- it now carries the full signal-hint set, plus the manual
fact note appended by :meth:`_prepare_update_prompt`).
"""
hints: list[str] = []
if "correction" in signals:
hints.append(
"IMPORTANT: Explicit correction signals were detected in this conversation. "
"Record a correction with confidence >= 0.95 only when it describes a durable, user-level "
"working preference that is safe to reuse across unrelated tasks. A correction to facts, files, "
"directions, or constraints in the current task is thread- or project-scoped and must not be stored."View on GitHub (pinned to 1dd6ba1acb)
Solutions
- Retry the update after the concurrent write settles
- Serialize memory mutations per agent to avoid revision races entirely
- Verify storage writability and space if the error repeats deterministically
Defensive patterns
Strategy: retry
Try / catch
try:
memory.update_memory_fact(fact_id, content=content, agent_name=agent)
except OSError:
time.sleep(0.2)
memory.update_memory_fact(fact_id, content=content, agent_name=agent) Prevention
- Avoid overlapping user edits with background memory-update writes
- Track storage health; persistent OSError after retries means I/O, not a race
When it happens
Trigger: Concurrent memory writes (background updater vs. user edit) winning the revision race, or the memory file being unwritable/full at save time.
Common situations: Fact edits racing scheduled memory-update jobs; degraded storage volumes.
Related errors
- Failed to save memory data after creating fact
- Failed to save memory data after deleting fact '{fact_id}'
- Failed to update global memory summaries
- Failed to save imported memory data
- Failed to save cleared memory data
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/170e2029e9f12892.
Report an issue: GitHub.