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 without

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Run the deermem backend (memory.manager_class: deermem) when per-fact editing is a requirement.
  2. Emulate the update on capable-remote backends as delete+recreate through the backend's supported paths, or let middleware-mode extraction correct facts conversationally.
  3. Custom backend authors: override update_fact on the MemoryManager subclass, preserving omitted-field semantics.
  4. 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

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


AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14). Data as JSON: /api/errors/a62c2b0f178470f3. Report an issue: GitHub.