bytedance/deer-flow · error · ValueError

mem0 failure_policy has unknown keys: {sorted(unknown_fp)}

Error message

mem0 failure_policy has unknown keys: {sorted(unknown_fp)}

What it means

Raised by Mem0Config.from_backend_config when memory.backend_config.failure_policy is a mapping but contains keys other than the two supported directions: read and write. Unknown keys are rejected so that a typo like reads or right does not silently disable a policy the operator believed was active.

Source

Thrown at backend/packages/harness/deerflow/agents/memory/backends/mem0/config.py:79

            - {
                "api_key_env",
                "base_url",
                "allow_insecure_http",
                "top_k",
                "score_threshold",
                "max_injection_chars",
                "timeout_seconds",
                "startup_policy",
            }
            - _HOST_INJECTED_KEYS
        )
        if unknown:
            raise ValueError(f"mem0 backend_config has unknown keys: {sorted(unknown)}")
        if not isinstance(failure_policy, dict):
            raise ValueError("mem0 failure_policy must be a mapping {read, write}")
        unknown_fp = set(failure_policy) - {"read", "write"}
        if unknown_fp:
            raise ValueError(f"mem0 failure_policy has unknown keys: {sorted(unknown_fp)}")
        allow_insecure_http = cfg.get("allow_insecure_http", False)
        if not isinstance(allow_insecure_http, bool):
            raise ValueError("mem0 allow_insecure_http must be a boolean")

        config = cls(
            api_key_env=str(cfg.get("api_key_env", "MEM0_API_KEY")),
            base_url=str(cfg.get("base_url", "https://api.mem0.ai")).rstrip("/"),
            allow_insecure_http=allow_insecure_http,
            top_k=int(cfg.get("top_k", 8)),
            score_threshold=float(cfg.get("score_threshold", 0.1)),
            max_injection_chars=int(cfg.get("max_injection_chars", 12000)),
            timeout_seconds=float(cfg.get("timeout_seconds", 10.0)),
            startup_policy=str(cfg.get("startup_policy", "fail_fast")),
            read_policy=str(failure_policy.get("read", "fail_open")),
            write_policy=str(failure_policy.get("write", "log_and_drop")),
        )
        if config.startup_policy not in _STARTUP_POLICIES:
            raise ValueError(f"mem0 startup_policy must be one of {sorted(_STARTUP_POLICIES)}")

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Rename the offending key to read or write — the sorted list in the message names exactly which keys are invalid
  2. Move non-policy options where they belong (e.g. startup_policy is a top-level backend_config key)
  3. Remove keys you do not need; read and write each have safe defaults

Example fix

# before (config.yaml)
memory:
  backend_config:
    failure_policy:
      read: fail_open
      writes: log_and_drop   # typo -> ValueError

# after
memory:
  backend_config:
    failure_policy:
      read: fail_open
      write: log_and_drop
Defensive patterns

Strategy: validation

Validate before calling

def failure_policy_keys_ok(backend_config: dict) -> bool:
    fp = (backend_config or {}).get("failure_policy") or {}
    return isinstance(fp, dict) and set(fp) <= {"read", "write"}

Prevention

When it happens

Trigger: failure_policy: {read: fail_open, writes: log_and_drop} — 'writes' is rejected; also extra invented keys like failure_policy: {read: ..., write: ..., startup: ...}.

Common situations: Typo in read/write key names; copy-pasting a policy block from another backend or older docs with extra keys; assuming failure_policy also carries startup_policy-style options.

Related errors


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