bytedance/deer-flow · error · ValueError

mem0 failure_policy.read must be one of {sorted(_READ_POLICI

Error message

mem0 failure_policy.read must be one of {sorted(_READ_POLICIES)}

What it means

Raised by Mem0Config.from_backend_config when memory.backend_config.failure_policy.read is not one of the two supported values: fail_open (default; recall errors inject nothing and the run continues) and fail_closed (recall errors raise MemoryManagerError). Checked after str() coercion, so any other string — typos, case variants, synonyms — is rejected.

Source

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

        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)}")
        if config.read_policy not in _READ_POLICIES:
            raise ValueError(f"mem0 failure_policy.read must be one of {sorted(_READ_POLICIES)}")
        if config.write_policy not in _WRITE_POLICIES:
            raise ValueError(f"mem0 failure_policy.write must be one of {sorted(_WRITE_POLICIES)}")
        if not 1 <= config.top_k <= 1000:
            raise ValueError("mem0 top_k must be in [1, 1000]")
        if not 0.0 <= config.score_threshold <= 1.0:
            raise ValueError("mem0 score_threshold must be in [0, 1]")
        if config.max_injection_chars <= 0:
            raise ValueError("mem0 max_injection_chars must be positive")
        if config.timeout_seconds <= 0:
            raise ValueError("mem0 timeout_seconds must be positive")
        if not config.api_key_env.strip():
            raise ValueError("mem0 api_key_env must be a non-empty env var name")
        parsed_base_url = urlsplit(config.base_url)
        if parsed_base_url.scheme not in {"http", "https"} or not parsed_base_url.netloc:
            raise ValueError("mem0 base_url must be an absolute http:// or https:// URL")
        if parsed_base_url.scheme == "http" and not config.allow_insecure_http:
            raise ValueError("mem0 base_url must use https:// because it carries the API key; set allow_insecure_http: true only for trusted local development")
        return config

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Use exactly fail_open (log + inject nothing on recall failure) or fail_closed (raise MemoryManagerError)
  2. For graceful degradation keep the default fail_open; use fail_closed only when memory recall must be guaranteed
  3. Remove the read key to accept the fail_open default

Example fix

# before (config.yaml)
memory:
  backend_config:
    failure_policy:
      read: ignore   # not a policy value

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

Strategy: validation

Validate before calling

READ_POLICIES = {"fail_open", "fail_closed"}

def read_policy_ok(backend_config: dict) -> bool:
    fp = (backend_config or {}).get("failure_policy") or {}
    return str(fp.get("read", "fail_open")) in READ_POLICIES

Type guard

def is_read_policy(v: object) -> bool:
    return v in ("fail_open", "fail_closed")

Prevention

When it happens

Trigger: failure_policy: {read: open}, {read: fail-closed}, {read: FailOpen}, or {read: ignore} in backend_config.

Common situations: Vocabulary drift from other backends' docs; typos; trying to express 'never fail' with words like ignore/skip/soft.

Related errors


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