bytedance/deer-flow · error · NotImplementedError
update_fact not supported by {type(self).__name__}
Error message
update_fact not supported by {type(self).__name__} What it means
MemoryManager.update_fact raises NotImplementedError as the optional per-fact CRUD default for partial fact updates (content/category/confidence with omitted fields preserved). Like create_fact/delete_fact, it is a DeerMem capability: backends without locally-addressable fact records (noop, mem0, honcho, openviking) inherit the raising default. The error indicates the selected memory backend does not support editing individual facts.
Source
Thrown at backend/packages/harness/deerflow/agents/memory/manager.py:431
*,
agent_name: str | None = None,
user_id: str | None = None,
) -> dict[str, Any]:
"""Delete one fact by id. Default: unsupported."""
raise NotImplementedError(f"delete_fact not supported by {type(self).__name__}")
def update_fact(
self,
fact_id: str,
content: str | None = None,
category: str | None = None,
confidence: float | None = None,
*,
agent_name: str | None = None,
user_id: str | None = None,
) -> dict[str, Any]:
"""Update one fact by id (preserving omitted fields). Default: unsupported."""
raise NotImplementedError(f"update_fact not supported by {type(self).__name__}")
# B-class: no agent-side caller yet -- signatures only, for future scenarios.
# Default no-op so callers can invoke unconditionally without gating. (The
# self-serving hooks on_delegation / on_session_end / on_memory_write are
# deliberately NOT contracted: no caller, no event source, or subsumed by
# the callbacks field.)
def on_pre_compress(self, messages: list[Any]) -> str:
"""Memory -> compressor feedback (future memory-driven summary
enrichment). Returns text to inject into the compression prompt
(default: none)."""
return ""
def on_turn_start(self, turn_number: int, message: Any, **kwargs: Any) -> None:
"""Turn-start nudge (future background review). Default: no-op."""
return None
# ── Async (speculative) ──────────────────────────────────────────────
# Interface placeholders so a future async LLM client can override withoutView on GitHub (pinned to 1dd6ba1acb)
Solutions
- Run the deermem backend (memory.manager_class: deermem) when per-fact editing is a requirement.
- Emulate the update on capable-remote backends as delete+recreate through the backend's supported paths, or let middleware-mode extraction correct facts conversationally.
- Custom backend authors: override update_fact on the MemoryManager subclass, preserving omitted-field semantics.
- Capability-check before exposing edit actions in tooling.
Example fix
# before
memory = manager.update_fact(fact_id, confidence=0.9, user_id="u1")
# after
if type(manager).update_fact is MemoryManager.update_fact:
raise UnsupportedOperation("fact updates unsupported by this backend")
memory = manager.update_fact(fact_id, confidence=0.9, user_id="u1") Defensive patterns
Strategy: type-guard
Validate before calling
from deerflow.agents.memory.manager import MemoryManager
def supports_fact_update(manager: MemoryManager) -> bool:
return type(manager).update_fact is not MemoryManager.update_fact Type guard
def supports_fact_update(manager: MemoryManager) -> bool:
"""True when the backend supports partial per-fact updates."""
return type(manager).update_fact is not MemoryManager.update_fact Try / catch
try:
memory = manager.update_fact(fact_id, content=new_text, user_id=uid)
except NotImplementedError as e:
raise UnsupportedMemoryOperation(str(e)) from e Prevention
- Gate fact-edit actions on supports_fact_update() before rendering them.
- For remote backends, correct facts conversationally (middleware extraction) instead of scripted update_fact calls.
- Document per-backend CRUD matrices wherever memory.manager_class is configured.
When it happens
Trigger: Calling MemoryManager.update_fact(fact_id, content=..., confidence=..., agent_name=..., user_id=...) — via the memory_update tool in memory.mode: tool, a fact-editing UI action, or a script — while memory.manager_class resolves to a backend that does not override update_fact.
Common situations: Editing a fact in a settings UI after the deployment switched to a remote memory backend; memory.mode: tool runs against mem0/honcho; scripted fact corrections (e.g. updating confidence thresholds) written for the default file backend.
Related errors
- create_fact not supported by {type(self).__name__}
- delete_fact not supported by {type(self).__name__}
- import_memory not supported by {type(self).__name__}
- reload_memory not supported by {type(self).__name__}
- search not supported by {type(self).__name__}
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/a62c2b0f178470f3.
Report an issue: GitHub.