bytedance/deer-flow · error · MemoryManagerError

honcho memory recall failed: {exc}

Error message

honcho memory recall failed: {exc}

What it means

Wrapped as MemoryManagerError by HonchoManager._read_or_fallback, the single failure_policy.read gate for every recall path. When read_fail_closed is true (failure_policy.read: fail_closed) and any exception other than an already-raised MemoryManagerError escapes a recall call (HTTP failure, timeout, Honcho server error), it is rethrown as MemoryManagerError; with the default fail_open policy the same exception is only logged at warning level and the fallback value (empty memory) is returned. The broad except is the containment boundary so no client exception escapes into MemoryMiddleware.after_agent.

Source

Thrown at backend/packages/harness/deerflow/agents/memory/backends/honcho/honcho_manager.py:150

        return f"{self._config.workspace_prefix}{_stable_id(user_id)}"

    def _user_peer(self, user_id: str) -> str:
        return self._config.user_peer_overrides.get(user_id) or _stable_id(user_id)

    # ── recall policy gate (get_context / search / get_memory) ───────────
    def _read_or_fallback(self, fallback: Any, fn: Any) -> Any:
        """Single ``failure_policy.read`` gate for every recall path, mirroring
        mem0's helper of the same name: fail-open (default) logs and returns
        ``fallback``; ``fail_closed`` wraps into ``MemoryManagerError``. The
        broad ``except Exception`` is the containment boundary — no client
        exception may escape into ``MemoryMiddleware.after_agent``."""
        try:
            return fn()
        except MemoryManagerError:
            raise
        except Exception as exc:
            if self._config.read_fail_closed:
                raise MemoryManagerError(f"honcho memory recall failed: {exc}") from exc
            logger.warning("honcho memory: recall failed (fail-open): %s", exc)
            return fallback

    # ── Tier 1: write ────────────────────────────────────────────────────
    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:
        workspace = self._workspace(user_id)
        if workspace is None or not user_id:
            logger.debug("honcho memory: no resolvable user for thread %s; skipping write", thread_id)
            return
        user_peer = self._user_peer(user_id)

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Verify the Honcho server is reachable: curl the base_url (e.g. GET /health or /v1/... ) from the Gateway host
  2. Check base_url correctness and network/DNS; fix any http/https or port mismatch in backend_config
  3. If recalls are hitting timeout_seconds under load, raise timeout_seconds/connect_timeout_seconds in backend_config
  4. If memory recall should degrade gracefully instead of failing the run, remove failure_policy.read: fail_closed to return to the default fail_open (log + inject nothing)

Example fix

# before (config.yaml)
memory:
  manager_class: honcho
  backend_config:
    base_url: http://honcho:8000   # wrong host -> every recall raises
    failure_policy:
      read: fail_closed

# after
memory:
  manager_class: honcho
  backend_config:
    base_url: http://localhost:8000
    failure_policy:
      read: fail_open   # recall failures log a warning and inject no memory
Defensive patterns

Strategy: try-catch

Validate before calling

import httpx

def honcho_reachable(base_url: str, timeout: float = 3.0) -> bool:
    try:
        return httpx.get(f"{base_url.rstrip('/')}/health", timeout=timeout).is_success
    except httpx.HTTPError:
        return False

Try / catch

from deerflow.agents.memory import MemoryManagerError

try:
    context = manager.get_context(thread_id=..., user_id=...)
except MemoryManagerError as e:
    # raised only when failure_policy.read == fail_closed;
    # decide: fail the run, or degrade to no-memory and continue
    logger.error("honcho recall failed (fail_closed): %s", e)
    context = ""

Prevention

When it happens

Trigger: memory.manager_class: honcho with backend_config.failure_policy.read: fail_closed, then any Honcho recall (get_context/search during MemoryMiddleware.after_agent or a memory_search tool call) hitting a connection error, timeout (timeout_seconds default 10s), 4xx/5xx from the Honcho server, or unexpected response shape.

Common situations: Honcho server down or unreachable at base_url; wrong base_url; TLS/firewall issues; honcho slowed beyond timeout_seconds under load; operator switched to fail_closed to make memory outages visible and now every Honcho blip fails the agent run.

Related errors


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