{"record":{"id":"278afbae4d3aa715","repo":"bytedance/deer-flow","slug":"reload-memory-not-supported-by-type-self-name","errorCode":null,"errorMessage":"reload_memory not supported by {type(self).__name__}","messagePattern":"reload_memory not supported by (.+?)","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"warning","filePath":"backend/packages/harness/deerflow/agents/memory/manager.py","lineNumber":395,"sourceCode":"          * ``None``  -- this backend has nothing to warm (the default). The\n            host logs a \"skipping\" message instead of the misleading \"warmed\n            successfully\", so a non-DeerMem backend doesn't claim a tiktoken\n            cache it never touched.\n\n        Backends with heavy one-time init override and return ``True``/``False``.\n        \"\"\"\n        return None\n\n    def reload_memory(\n        self,\n        *,\n        user_id: str | None = None,\n        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        *,","sourceCodeStart":377,"sourceCodeEnd":413,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/packages/harness/deerflow/agents/memory/manager.py#L377-L413","documentation":"MemoryManager.reload_memory raises NotImplementedError as the base-class default for backends without a cached memory document. The method's contract is 'drop the cached document and reload from storage', which only makes sense for backends that cache (DeerMem overrides it); remote backends have no local cache to invalidate, so they inherit the raising default. The docstring notes callers are expected to fall back to get_memory() when the backend does not support reload.","triggerScenarios":"Invoking MemoryManager.reload_memory(user_id=..., agent_name=...) — e.g. POST /api/memory/reload, DeerFlowClient.reload_memory(), or a direct call — while the configured backend does not override it (noop, mem0, honcho, openviking). Out-of-band edits to DeerMem's Markdown fact files require reload(), which is why this path exists at all.","commonSituations":"POST /api/memory/reload after switching memory.manager_class to honcho or mem0 in config.yaml; calling DeerFlowClient.reload_memory() in an embedded integration against a non-DeerMem backend; test suites exercising the reload route against the noop backend.","solutions":["Call get_memory() instead — the documented fallback for backends without reload support; it returns the current view without a cache drop.","If you need true reload semantics (out-of-band file edits), run the deermem backend (memory.manager_class: deermem).","Backend authors: override reload_memory() on the MemoryManager subclass when your backend caches documents.","API/tooling authors: catch NotImplementedError on reload and degrade to get_memory() rather than surfacing a 500."],"exampleFix":"# before\nmemory = client.reload_memory()  # or manager.reload_memory(user_id=\"u1\")\n\n# after\ntry:\n    memory = manager.reload_memory(user_id=\"u1\")\nexcept NotImplementedError:\n    memory = manager.get_memory(user_id=\"u1\")  # documented fallback","handlingStrategy":"fallback","validationCode":"from deerflow.agents.memory.manager import MemoryManager\n\nif type(manager).reload_memory is MemoryManager.reload_memory:\n    memory = manager.get_memory(user_id=uid)  # documented fallback path\nelse:\n    memory = manager.reload_memory(user_id=uid)","typeGuard":"def supports_reload(manager: MemoryManager) -> bool:\n    \"\"\"True when the backend has a cache and overrides reload_memory.\"\"\"\n    return type(manager).reload_memory is not MemoryManager.reload_memory","tryCatchPattern":"try:\n    memory = manager.reload_memory(user_id=uid)\nexcept NotImplementedError:\n    memory = manager.get_memory(user_id=uid)  # callers fall back per the contract docstring","preventionTips":["Treat reload as an optimization (cache invalidation), never a correctness requirement — always have get_memory as the fallback.","Only expose 'force reload' UI affordances when supports_reload() is true.","For out-of-band edits to DeerMem fact files, prefer stopping writes and using reload on the backend that supports it."],"tags":["memory","not-implemented","cache","deerflow"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}