{"record":{"id":"28b00eaf0c2b8cd7","repo":"bytedance/deer-flow","slug":"mem0-backend-config-has-unknown-keys-sorted-unkn","errorCode":null,"errorMessage":"mem0 backend_config has unknown keys: {sorted(unknown)}","messagePattern":"mem0 backend_config has unknown keys: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/packages/harness/deerflow/agents/memory/backends/mem0/config.py","lineNumber":74,"sourceCode":"    def from_backend_config(cls, backend_config: dict[str, Any] | None) -> Mem0Config:\n        cfg = dict(backend_config or {})\n        failure_policy = cfg.pop(\"failure_policy\", {}) or {}\n        unknown = (\n            set(cfg)\n            - {\n                \"api_key_env\",\n                \"base_url\",\n                \"allow_insecure_http\",\n                \"top_k\",\n                \"score_threshold\",\n                \"max_injection_chars\",\n                \"timeout_seconds\",\n                \"startup_policy\",\n            }\n            - _HOST_INJECTED_KEYS\n        )\n        if unknown:\n            raise ValueError(f\"mem0 backend_config has unknown keys: {sorted(unknown)}\")\n        if not isinstance(failure_policy, dict):\n            raise ValueError(\"mem0 failure_policy must be a mapping {read, write}\")\n        unknown_fp = set(failure_policy) - {\"read\", \"write\"}\n        if unknown_fp:\n            raise ValueError(f\"mem0 failure_policy has unknown keys: {sorted(unknown_fp)}\")\n        allow_insecure_http = cfg.get(\"allow_insecure_http\", False)\n        if not isinstance(allow_insecure_http, bool):\n            raise ValueError(\"mem0 allow_insecure_http must be a boolean\")\n\n        config = cls(\n            api_key_env=str(cfg.get(\"api_key_env\", \"MEM0_API_KEY\")),\n            base_url=str(cfg.get(\"base_url\", \"https://api.mem0.ai\")).rstrip(\"/\"),\n            allow_insecure_http=allow_insecure_http,\n            top_k=int(cfg.get(\"top_k\", 8)),\n            score_threshold=float(cfg.get(\"score_threshold\", 0.1)),\n            max_injection_chars=int(cfg.get(\"max_injection_chars\", 12000)),\n            timeout_seconds=float(cfg.get(\"timeout_seconds\", 10.0)),\n            startup_policy=str(cfg.get(\"startup_policy\", \"fail_fast\")),","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/packages/harness/deerflow/agents/memory/backends/mem0/config.py#L56-L92","documentation":"Raised by Mem0Config.from_backend_config when memory.backend_config (with manager_class: mem0) contains keys outside the accepted set {api_key_env, base_url, allow_insecure_http, top_k, score_threshold, max_injection_chars, timeout_seconds, startup_policy} plus the host-injected {storage_path, should_keep_hidden_message} (accepted and ignored). This is deliberate fail-fast design: a typo in persistent-state config must not silently fall back to defaults.","triggerScenarios":"Adding any extra key under memory.backend_config, e.g. api_key (the mem0 backend takes the key via env var, not config), failure_policy is fine (popped before the check) but failure_policies is an unknown key, mem0_api_key, max_tokens, or a key that only the honcho backend understands (workspace_prefix, assistant_peer).","commonSituations":"Copy-pasting honcho or generic backend options into the mem0 block; trying to put the API key in config (must use api_key_env env var instead); version drift — using a key from a newer/older DeerFlow docs page; leftover experimental keys after an upgrade.","solutions":["Remove or correct the key(s) listed in the message — the sorted unknown list tells you exactly which ones are rejected","If you meant to supply the API key, set api_key_env: MEM0_API_KEY (name only) and export the key in the environment; the key value itself is never valid in config","Move per-backend policy settings under failure_policy: {read, write} which is validated separately","Check the mem0 backend section of the DeerFlow memory docs for the exact supported key set"],"exampleFix":"# before (config.yaml)\nmemory:\n  manager_class: mem0\n  backend_config:\n    api_key: \"m0-sk-...\"        # unknown key -> ValueError\n    top_k: 8\n\n# after\nmemory:\n  manager_class: mem0\n  backend_config:\n    api_key_env: MEM0_API_KEY   # key value goes in the environment\n    top_k: 8","handlingStrategy":"validation","validationCode":"ALLOWED = {\"api_key_env\", \"base_url\", \"allow_insecure_http\", \"top_k\",\n           \"score_threshold\", \"max_injection_chars\", \"timeout_seconds\",\n           \"startup_policy\", \"failure_policy\", \"storage_path\", \"should_keep_hidden_message\"}\n\ndef mem0_config_keys_ok(backend_config: dict) -> bool:\n    return not (set(backend_config or {}) - ALLOWED)\n\n# Stronger: parse it for real — this runs every validation rule.\nfrom deerflow.agents.memory.backends.mem0.config import Mem0Config\nMem0Config.from_backend_config(backend_config)  # raises ValueError on any problem","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate config in CI/deploy by calling Mem0Config.from_backend_config on the rendered config before rollout","Never place the API key value in backend_config — only api_key_env (the env var name)","Per-backend options are not portable: honcho keys (workspace_prefix, assistant_peer, ...) are rejected by the mem0 parser"],"tags":["config","mem0","memory","validation","yaml"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}