{"record":{"id":"34204b67832bac1a","repo":"bytedance/deer-flow","slug":"invalid-openviking-peer-scope-agent-name-r","errorCode":null,"errorMessage":"Invalid OpenViking peer scope: {agent_name!r}","messagePattern":"Invalid OpenViking peer scope: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/packages/harness/deerflow/agents/memory/backends/openviking/session.py","lineNumber":28,"sourceCode":"from .config import GENERATED_PEER_PREFIX, is_safe_peer_id\n\n_SESSION_NAMESPACE = \"deerflow-openviking-adapter-v1\"\n_DEFAULT_AGENT_SCOPE = \"__default__\"\n_CURSOR_SCHEMA_VERSION = 1\n\n\ndef _canonical_peer_id(\n    agent_name: str | None,\n    default_peer_id: str,\n) -> str:\n    \"\"\"Map DeerFlow's case-insensitive agent names to disjoint peer IDs.\"\"\"\n\n    if agent_name is None:\n        return default_peer_id\n\n    value = str(agent_name).strip().lower()\n    if not value or value == _DEFAULT_AGENT_SCOPE:\n        raise ValueError(f\"Invalid OpenViking peer scope: {agent_name!r}\")\n    if is_safe_peer_id(value) and value != default_peer_id and not value.startswith(GENERATED_PEER_PREFIX):\n        return value\n\n    # The generated namespace is reserved, so compatible names, the default\n    # peer, and hashed fallbacks cannot alias one another. The 128-bit digest\n    # also avoids collisions caused by sanitizing or truncating agent names.\n    digest = hashlib.sha256(value.encode(\"utf-8\")).hexdigest()[:32]\n    return f\"{GENERATED_PEER_PREFIX}{digest}\"\n\n\ndef _session_id(\n    owner_user_id: str,\n    peer_id: str,\n    thread_id: str,\n) -> str:\n    \"\"\"Derive one stable OpenViking session for one DeerFlow thread.\"\"\"\n\n    digest = hashlib.sha256(f\"{_SESSION_NAMESPACE}\\0{owner_user_id}\\0{peer_id}\\0{thread_id}\".encode()).hexdigest()","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/packages/harness/deerflow/agents/memory/backends/openviking/session.py#L10-L46","documentation":"_canonical_peer_id() in session.py raises ValueError when the supplied agent_name, after strip().lower(), is empty or equals the reserved default scope '__default__'. Agent names are mapped to disjoint OpenViking actor peer IDs; the default scope is reserved for the manager-level default (agent_name=None) and cannot be passed explicitly, and an empty name has no peer identity.","triggerScenarios":"Calling memory operations with agent_name='' , agent_name='   ', or agent_name='__default__' (case-insensitive). Other unsafe names do not raise — they are hashed into the reserved 'df-agent-' namespace instead; only these two degenerate forms are rejected.","commonSituations":"Passing the DeerMem sentinel '__default__' explicitly through the OpenViking backend (only DeerMem storage accepts it); a caller building agent_name from empty config or an unset subagent name.","solutions":["Pass agent_name=None when you mean the default peer — the manager substitutes config default_peer_id","Use a real non-empty agent name; any unsafe characters are automatically hashed, so no sanitization is needed","Never forward DeerMem's '__default__' sentinel to OpenViking-backed operations"],"exampleFix":"# before\nmanager.add(thread_id, msgs, agent_name='__default__', user_id='default')\n\n# after\nmanager.add(thread_id, msgs, agent_name=None, user_id='default')","handlingStrategy":"validation","validationCode":"def safe_agent_name(agent_name: str | None) -> str | None:\n    if agent_name is None:\n        return None\n    normalized = str(agent_name).strip().lower()\n    if not normalized or normalized == \"__default__\":\n        return None  # or raise: explicit default scope is not a valid peer\n    return agent_name","typeGuard":"def is_valid_explicit_peer(agent_name: object) -> bool:\n    if not isinstance(agent_name, str):\n        return agent_name is None\n    v = agent_name.strip().lower()\n    return bool(v) and v != \"__default__\"","tryCatchPattern":null,"preventionTips":["Pass agent_name=None for the default peer; never forward '__default__' to OpenViking-backed calls","Validate agent names at your API boundary before they reach the memory manager"],"tags":["openviking","agent-name","validation","memory"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}