bytedance/deer-flow · error · NotImplementedError

delete_fact not supported by {type(self).__name__}

Error message

delete_fact not supported by {type(self).__name__}

What it means

MemoryManager.delete_fact raises NotImplementedError as the optional per-fact CRUD default: deleting one fact by id is only meaningful for backends that own discrete, addressable fact records — DeerMem. Remote/no-op backends (noop, mem0, honcho, openviking) inherit the raising default, so calling delete_fact on them is an explicit capability mismatch rather than a runtime failure of the store.

Source

Thrown at backend/packages/harness/deerflow/agents/memory/manager.py:418

        category: str = "context",
        confidence: float = 0.5,
        *,
        agent_name: str | None = None,
        user_id: str | None = None,
    ) -> tuple[dict[str, Any], str | None]:
        """Manually add one fact. Returns ``(memory_data, fact_id)`` -- ``fact_id``
        is None when a storage cap evicted the just-added fact. Default: unsupported."""
        raise NotImplementedError(f"create_fact not supported by {type(self).__name__}")

    def delete_fact(
        self,
        fact_id: str,
        *,
        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

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Switch to a backend implementing fact CRUD (memory.manager_class: deermem) if per-fact deletion is required.
  2. Use the backend's own deletion mechanism (its native API or clearing memory via the supported clear path) instead of delete_fact.
  3. Custom backends: override delete_fact on the MemoryManager subclass.
  4. Hide/disable delete affordances when the backend lacks the capability instead of calling and crashing.

Example fix

# before
memory = manager.delete_fact(fact_id, user_id="u1")  # NotImplementedError on remote backends

# after
try:
    memory = manager.delete_fact(fact_id, user_id="u1")
except NotImplementedError:
    memory = manager.clear_memory(user_id="u1")  # coarse fallback only if acceptable
Defensive patterns

Strategy: type-guard

Validate before calling

from deerflow.agents.memory.manager import MemoryManager

def supports_fact_delete(manager: MemoryManager) -> bool:
    return type(manager).delete_fact is not MemoryManager.delete_fact

Type guard

def supports_fact_delete(manager: MemoryManager) -> bool:
    """True when the backend can delete one fact by id."""
    return type(manager).delete_fact is not MemoryManager.delete_fact

Try / catch

try:
    memory = manager.delete_fact(fact_id, user_id=uid)
except NotImplementedError as e:
    raise UnsupportedMemoryOperation(str(e)) from e  # permanent, not retryable

Prevention

When it happens

Trigger: Calling MemoryManager.delete_fact(fact_id, agent_name=..., user_id=...) — via the memory_delete tool in memory.mode: tool, a management API route, or directly — while the configured manager_class does not override it. The fact_id comes from a prior get_memory()/create_fact() response, so it typically surfaces in fact-management UIs after a backend switch.

Common situations: A fact-management interface built against deermem being used after config.yaml switched memory.manager_class to mem0/honcho; memory.mode: tool enabled with a remote backend; cleanup scripts iterating fact lists and deleting by id.

Related errors


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