{"record":{"id":"15a73255e43d9272","repo":"bytedance/deer-flow","slug":"honcho-backend-key-k-r-has-an-empty-value-r","errorCode":null,"errorMessage":"Honcho backend: {key}[{k!r}] has an empty value; remove the entry or set a non-empty id.","messagePattern":"Honcho backend: (.+?)\\[(.+?)\\] has an empty value; remove the entry or set a non-empty id\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/packages/harness/deerflow/agents/memory/backends/honcho/config.py","lineNumber":31,"sourceCode":"from typing import Any\n\n_ID_RE = re.compile(r\"[^a-zA-Z0-9_-]+\")\n\n\ndef sanitize_id(raw: str) -> str:\n    \"\"\"Map an arbitrary string onto Honcho's id grammar (``^[a-zA-Z0-9_-]+$``; grammar allows up to 100, capped here at 64).\"\"\"\n    return _ID_RE.sub(\"-\", str(raw)).strip(\"-\")[:64]\n\n\ndef _parse_override_map(cfg: dict[str, Any], key: str) -> dict[str, str]:\n    \"\"\"Overrides map raw user ids to explicit workspace/peer ids; an empty or\n    null VALUE is always a config mistake (empty string is falsy and would\n    silently fall through to the default derivation; YAML null would stringify\n    into an id literally named \"None\"), so fail fast at parse time.\"\"\"\n    out: dict[str, str] = {}\n    for k, v in (cfg.get(key) or {}).items():\n        if v is None or not str(v).strip():\n            raise ValueError(f\"Honcho backend: {key}[{k!r}] has an empty value; remove the entry or set a non-empty id.\")\n        out[str(k)] = str(v)\n    return out\n\n\n@dataclass\nclass HonchoConfig:\n    base_url: str = \"http://localhost:8000\"\n    api_key: str | None = None\n    workspace_prefix: str = \"deerflow-u-\"\n    workspace_overrides: dict[str, str] = field(default_factory=dict)\n    user_peer_overrides: dict[str, str] = field(default_factory=dict)\n    assistant_peer: str = \"deerflow\"\n    timeout_seconds: float = 10.0\n    connect_timeout_seconds: float = 3.0\n    message_char_limit: int = 8000\n    max_injection_chars: int = 6000\n    allow_insecure_http: bool = False\n    read_fail_closed: bool = False","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/packages/harness/deerflow/agents/memory/backends/honcho/config.py#L13-L49","documentation":"Raised by HonchoConfig.from_backend_config when a workspace_overrides or user_peer_overrides mapping in memory.backend_config contains an entry whose value is null or an empty/whitespace-only string. These overrides map raw DeerFlow user ids to explicit Honcho workspace/peer ids, so an empty value would silently fall through to the default id derivation (empty string is falsy) or stringify YAML null into an id literally named 'None'. The backend fails fast at parse time instead.","triggerScenarios":"Setting memory.manager_class: honcho with backend_config.workspace_overrides: {\"user@example.com\": } or {\"user@example.com\": \"\"} or {\"user@example.com\": null} in config.yaml (a YAML key with no value parses as null). Same for user_peer_overrides.","commonSituations":"YAML entries where the value was deleted but the key left behind; commenting out a value but not the key; copying an example config with placeholder empty values; intending 'use the default' for one user while overriding others (not supported — remove the entry instead).","solutions":["Remove the offending key from workspace_overrides/user_peer_overrides so that user falls back to the default derivation (workspace_prefix + sanitized id)","Set the entry to a real non-empty Honcho workspace/peer id, e.g. workspace_overrides: {\"user@example.com\": \"team-a-ws\"}","Check for stray 'key:' lines with no value in config.yaml — YAML parses them as null"],"exampleFix":"# before (config.yaml)\nmemory:\n  manager_class: honcho\n  backend_config:\n    workspace_overrides:\n      user@example.com:   # null value -> ValueError\n\n# after\nmemory:\n  manager_class: honcho\n  backend_config:\n    workspace_overrides:\n      user@example.com: team-a-ws   # or delete the line entirely","handlingStrategy":"validation","validationCode":"from deerflow.agents.memory.backends.honcho.config import HonchoConfig\n\ntry:\n    HonchoConfig.from_backend_config(backend_config)\nexcept ValueError as e:\n    # surface at config-load time with a clear operator message\n    raise SystemExit(f\"invalid honcho backend_config: {e}\")","typeGuard":null,"tryCatchPattern":"try:\n    cfg = HonchoConfig.from_backend_config(backend_config)\nexcept ValueError as e:\n    # parse-time config error: fail fast, do not fall back to defaults\n    raise","preventionTips":["Lint config.yaml for mapping entries with null/empty values (a simple 'key:' with no value check catches most cases)","Treat overrides maps as all-or-nothing: every key must map to a literal non-empty id","Run the Gateway config preflight (make doctor / startup config parse) before deploying config changes"],"tags":["config","honcho","memory","yaml","validation"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}