{"record":{"id":"fad778fb8a78ec32","repo":"bytedance/deer-flow","slug":"create-fact-not-supported-by-type-self-name","errorCode":null,"errorMessage":"create_fact not supported by {type(self).__name__}","messagePattern":"create_fact not supported by (.+?)","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"backend/packages/harness/deerflow/agents/memory/manager.py","lineNumber":408,"sourceCode":"        agent_name: str | None = None,\n    ) -> dict[str, Any]:\n        \"\"\"Drop the cached memory document and reload from storage. Default:\n        unsupported (callers fall back to :meth:`get_memory`). Backends with a\n        cache override.\"\"\"\n        raise NotImplementedError(f\"reload_memory not supported by {type(self).__name__}\")\n\n    def create_fact(\n        self,\n        content: str,\n        category: str = \"context\",\n        confidence: float = 0.5,\n        *,\n        agent_name: str | None = None,\n        user_id: str | None = None,\n    ) -> tuple[dict[str, Any], str | None]:\n        \"\"\"Manually add one fact. Returns ``(memory_data, fact_id)`` -- ``fact_id``\n        is None when a storage cap evicted the just-added fact. Default: unsupported.\"\"\"\n        raise NotImplementedError(f\"create_fact not supported by {type(self).__name__}\")\n\n    def delete_fact(\n        self,\n        fact_id: str,\n        *,\n        agent_name: str | None = None,\n        user_id: str | None = None,\n    ) -> dict[str, Any]:\n        \"\"\"Delete one fact by id. Default: unsupported.\"\"\"\n        raise NotImplementedError(f\"delete_fact not supported by {type(self).__name__}\")\n\n    def update_fact(\n        self,\n        fact_id: str,\n        content: str | None = None,\n        category: str | None = None,\n        confidence: float | None = None,\n        *,","sourceCodeStart":390,"sourceCodeEnd":426,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/packages/harness/deerflow/agents/memory/manager.py#L390-L426","documentation":"MemoryManager.create_fact raises NotImplementedError as the base-class default for the manual fact-creation API. The method is part of the optional per-fact CRUD contract ('manually add one fact', returning (memory_data, fact_id)); only document-style backends that store discrete facts locally — DeerMem — implement it. Backends that delegate representation-building to a remote service (honcho), an external store (mem0, openviking), or that store nothing (noop) intentionally do not, so any direct create_fact call against them raises.","triggerScenarios":"Calling MemoryManager.create_fact(content, category=..., confidence=..., agent_name=..., user_id=...) — via the memory tool API, the /api/memory management surface, or directly — while memory.manager_class is noop, mem0, honcho, or openviking. Also fires in tool mode (memory.mode: tool) if the memory_add tool is routed to a backend without the primitive.","commonSituations":"Enabling memory.mode: tool with a remote backend selected in config.yaml; porting scripts that seed facts via create_fact from a deermem deployment to a mem0/honcho deployment; unit tests asserting CRUD behavior but running against the noop manager.","solutions":["Use a backend that implements fact CRUD: set memory.manager_class: deermem (the default file backend).","For remote backends, add facts through the backend's own supported write path (e.g. middleware-mode conversation capture, or the backend's native API) instead of create_fact.","Custom backend authors: override create_fact (and delete_fact/update_fact) on the MemoryManager subclass.","Gate UI/script features on backend capability rather than calling create_fact unconditionally."],"exampleFix":"# before\nmemory, fact_id = manager.create_fact(\"User prefers dark mode\", category=\"preference\")\n\n# after\nif not hasattr(type(manager), \"create_fact\") or type(manager).create_fact is MemoryManager.create_fact:\n    raise UnsupportedOperation(\"backend does not support manual fact creation\")\nmemory, fact_id = manager.create_fact(\"User prefers dark mode\", category=\"preference\")","handlingStrategy":"type-guard","validationCode":"from deerflow.agents.memory.manager import MemoryManager\n\ndef supports_fact_crud(manager: MemoryManager) -> bool:\n    return type(manager).create_fact is not MemoryManager.create_fact","typeGuard":"def supports_fact_crud(manager: MemoryManager) -> bool:\n    \"\"\"True when the backend implements manual per-fact creation.\"\"\"\n    return type(manager).create_fact is not MemoryManager.create_fact","tryCatchPattern":"try:\n    memory, fact_id = manager.create_fact(content, user_id=uid)\nexcept NotImplementedError as e:\n    # permanent capability gap: do not retry; use backend-supported write path\n    raise UnsupportedMemoryOperation(str(e)) from e","preventionTips":["Capability-check before enabling memory.mode: tool with non-DeerMem backends.","Surface backend capabilities in the memory status endpoint consumers (UI) so users cannot reach dead actions.","Pin tests to the backend actually configured, not to the full MemoryManager contract."],"tags":["memory","not-implemented","crud","deerflow"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}