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
- Align memory.backend_config.owner_user_id with the DeerFlow user actually issuing requests (in no-auth mode the effective user is 'default')
- 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
- 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
- Configure owner_user_id to the exact effective DeerFlow user ('default' in no-auth mode)
- Treat this error as a security boundary: never try to bypass it by rewriting user_id
- One OpenViking USER API key per deployment per user; multi-user needs separate configs
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
- Failed to update agent: ${res.statusText}
- Unable to recover SSE history after ${recoveryAttempts} atte
- detailMessage ?? `${fallbackMessage}: ${response.statusText}
- OpenViking health check returned an unhealthy response
- OpenViking memory write requires thread_id
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/acc7a7ff000cc1ff.
Report an issue: GitHub.