bytedance/deer-flow · error · ValueError

The OpenViking automatic-memory backend supports memory.mode

Error message

The OpenViking automatic-memory backend supports memory.mode='middleware' only; use OpenViking MCP for explicit model tools

What it means

OpenVikingMemoryManager.from_config() hard-rejects memory.mode='tool'. The OpenViking automatic-memory backend deliberately supports only passive middleware capture/recall; explicit model-facing memory tools are provided by the separate OpenViking MCP integration instead. Any other mode value raises this ValueError before the backend is constructed.

Source

Thrown at backend/packages/harness/deerflow/agents/memory/backends/openviking/openviking_manager.py:98

            limit=self._config.search_top_k,
            score_threshold=self._config.score_threshold,
            context_types=("memory",),
            content_mode=self._config.content_mode,
            max_content_chars=self._config.max_injection_chars,
        )
        self._use_actor_peer = integration["use_actor_peer"]
        self._partial_write_error = integration["OpenVikingPartialWriteError"]

    @classmethod
    def from_config(
        cls,
        backend_config: dict[str, Any] | None = None,
        *,
        mode: Literal["middleware", "tool"] = "middleware",
        **host_hooks: Any,
    ) -> OpenVikingMemoryManager:
        if mode != "middleware":
            raise ValueError("The OpenViking automatic-memory backend supports memory.mode='middleware' only; use OpenViking MCP for explicit model tools")
        instance = cls(backend_config=backend_config or {}, mode=mode)
        hidden_filter = host_hooks.get("should_keep_hidden_message")
        instance._should_keep_hidden_message = hidden_filter if callable(hidden_filter) else None
        return instance

    def add(
        self,
        thread_id: str,
        messages: list[Any],
        *,
        agent_name: str | None = None,
        user_id: str | None = None,
        trace_id: str | None = None,
    ) -> None:
        del trace_id
        self._write_conversation(
            thread_id,
            messages,

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Set memory.mode: middleware (or remove the key — middleware is the default) when memory.manager_class: openviking
  2. If you need explicit memory_search/memory_add model tools against OpenViking, use the OpenViking MCP integration instead of the automatic-memory backend
  3. Restart the Gateway after the config change

Example fix

# before (config.yaml)
memory:
  manager_class: openviking
  mode: tool

# after
memory:
  manager_class: openviking
  mode: middleware
Defensive patterns

Strategy: validation

Validate before calling

mode = memory_cfg.get("mode", "middleware")
manager_class = memory_cfg.get("manager_class")
assert not (manager_class == "openviking" and mode != "middleware"), "openviking backend requires memory.mode='middleware'; use OpenViking MCP for tool mode"

Type guard

def openviking_mode_compatible(memory_cfg: dict) -> bool:
    return memory_cfg.get("manager_class") != "openviking" or memory_cfg.get("mode", "middleware") == "middleware"

Prevention

When it happens

Trigger: Configuring config.yaml with memory.manager_class: openviking together with memory.mode: tool. The factory is invoked during memory manager construction at Gateway startup (or agent rebuild), so the process fails to bring the memory subsystem up.

Common situations: Switching an experimental tool-mode setup (previously used with honcho or DeerMem, which do support tool mode) to the OpenViking backend without changing memory.mode back to middleware.

Related errors


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