bytedance/deer-flow · error · ValueError

OpenViking {name} must be a mapping

Error message

OpenViking {name} must be a mapping

What it means

The _mapping() helper in the OpenViking config parser rejects a non-dict value for a section that must be a YAML mapping. Only two names are ever passed: 'retrieval' and 'failure_policy'. It fires when backend_config['retrieval'] or backend_config['failure_policy'] is a scalar or list instead of a dict; None is tolerated as an empty mapping.

Source

Thrown at backend/packages/harness/deerflow/agents/memory/backends/openviking/config.py:156

        if self.read_failure_policy not in {"fail_open", "raise"}:
            raise ValueError("OpenViking failure_policy.read must be 'fail_open' or 'raise'")
        if self.write_failure_policy not in {"log_and_drop", "raise"}:
            raise ValueError("OpenViking failure_policy.write must be 'log_and_drop' or 'raise'")
        if not 16 <= self.max_seen_message_ids <= 10_000:
            raise ValueError("OpenViking max_seen_message_ids must be between 16 and 10000")


def is_safe_peer_id(value: str) -> bool:
    """Return whether *value* is valid for an OpenViking actor peer."""

    return _SAFE_PEER_RE.fullmatch(value) is not None


def _mapping(value: Any, name: str) -> dict[str, Any]:
    if value is None:
        return {}
    if not isinstance(value, dict):
        raise ValueError(f"OpenViking {name} must be a mapping")
    return dict(value)


def _optional_float(value: Any) -> float | None:
    return None if value is None else float(value)


def _boolean(value: Any, name: str) -> bool:
    if isinstance(value, bool):
        return value
    if isinstance(value, str):
        normalized = value.strip().lower()
        if normalized in {"true", "1", "yes", "on"}:
            return True
        if normalized in {"false", "0", "no", "off"}:
            return False
    raise ValueError(f"OpenViking {name} must be a boolean")

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Make retrieval and failure_policy nested mappings in config.yaml: retrieval: {top_k: 8, ...}, failure_policy: {read: fail_open, write: log_and_drop}
  2. Verify with a YAML linter that the section parses to a dict, not a scalar/list
  3. Restart the Gateway after fixing config.yaml

Example fix

# before (config.yaml)
memory:
  backend_config:
    retrieval: 8

# after
memory:
  backend_config:
    retrieval:
      top_k: 8
Defensive patterns

Strategy: type-guard

Validate before calling

for section in ("retrieval", "failure_policy"):
    value = raw_backend_config.get(section)
    assert value is None or isinstance(value, dict), f"OpenViking {section} must be a mapping (dict), got {type(value).__name__}"

Type guard

def is_mapping_section(value: object) -> bool:
    return value is None or isinstance(value, dict)

Prevention

When it happens

Trigger: Writing memory.backend_config.retrieval: 8 or failure_policy: fail_open (a string) instead of a nested mapping, e.g. retrieval.top_k as a flat key or the whole section collapsed to one value. Raised inside OpenVikingConfig.from_backend_config before any other validation.

Common situations: Flattening YAML by mistake (retrieval: [top_k, 8] as a list), or copying an example that used a different schema shape. Distinct from the 'Unknown OpenViking backend_config fields' error, which fires for misplaced keys that are still valid YAML.

Related errors


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