bytedance/deer-flow · critical · MemoryManagerError

OpenViking USER API key is bound to DeerFlow owner_user_id {

Error message

OpenViking USER API key is bound to DeerFlow owner_user_id {self._config.owner_user_id!r}, but this request belongs to {resolved_user!r}. Refusing to share one credential across users.

What it means

OpenVikingMemoryManager._resolve_scope() raises MemoryManagerError when the resolved request user (user_id or 'default') differs from the configured owner_user_id. The backend is credential-bound: one OpenViking USER API key belongs to exactly one DeerFlow user, and the check deliberately fails closed to prevent one user's memory writes/reads being attributed to another under a shared credential.

Source

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

        self._save_cursor(
            session_id,
            _advanced_cursor(
                state,
                signatures,
                pending_signatures,
                max_seen=self._config.max_seen_message_ids,
                commit_pending=False,
            ),
        )

    def _resolve_scope(
        self,
        user_id: str | None,
        agent_name: str | None,
    ) -> str:
        resolved_user = str(user_id or "default")
        if resolved_user != self._config.owner_user_id:
            raise MemoryManagerError(f"OpenViking USER API key is bound to DeerFlow owner_user_id {self._config.owner_user_id!r}, but this request belongs to {resolved_user!r}. Refusing to share one credential across users.")
        return _canonical_peer_id(agent_name, self._config.default_peer_id)

    def _actor_peer_scope(
        self,
        peer_id: str,
    ) -> AbstractContextManager[None]:
        return self._use_actor_peer(peer_id)

    def _session_lock(self, session_id: str) -> threading.RLock:
        with self._session_locks_guard:
            return self._session_locks.setdefault(
                session_id,
                threading.RLock(),
            )

    def _begin_operation(self) -> bool:
        with self._lifecycle:
            if self._closed:

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Align memory.backend_config.owner_user_id with the DeerFlow user actually issuing requests (in no-auth mode the effective user is 'default')
  2. If multiple DeerFlow users must use OpenViking, give each user their own deployment/config with their own USER API key — this backend is single-user by design
  3. Restart the Gateway after changing owner_user_id

Example fix

# before (config.yaml): owner mismatch
memory:
  backend_config:
    owner_user_id: alice   # but the deployment runs without auth -> user resolves to 'default'

# after
memory:
  backend_config:
    owner_user_id: default
Defensive patterns

Strategy: validation

Validate before calling

owner = str(backend_config.get("owner_user_id", "")).strip()
resolved = str(user_id or "default")
if resolved != owner:
    raise PermissionError(f"request user {resolved!r} does not match OpenViking owner {owner!r}")

Type guard

def user_matches_owner(user_id: str | None, owner_user_id: str) -> bool:
    return str(user_id or "default") == owner_user_id

Try / catch

from deerflow.agents.memory.manager import MemoryManagerError
try:
    manager.add(thread_id, messages, user_id=user_id)
except MemoryManagerError as exc:
    if "Refusing to share one credential" in str(exc):
        reject_request_with_403()  # credential/user mismatch, do not retry
    raise

Prevention

When it happens

Trigger: memory.backend_config.owner_user_id is set to 'alice' but a request arrives with user_id='bob' (or no user_id, resolving to 'default' while owner_user_id is something else). Fires on both the write path (add) and read path (get injected context) of every OpenViking operation.

Common situations: Running multi-user/multi-tenant DeerFlow against the single-user OpenViking backend; enabling auth after having configured owner_user_id; IM channel traffic carrying a different owner header than the configured owner_user_id.

Related errors


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