{"record":{"id":"03c5eeaa7c5d991c","repo":"bytedance/deer-flow","slug":"openviking-name-must-be-a-mapping","errorCode":null,"errorMessage":"OpenViking {name} must be a mapping","messagePattern":"OpenViking (.+?) must be a mapping","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/packages/harness/deerflow/agents/memory/backends/openviking/config.py","lineNumber":156,"sourceCode":"        if self.read_failure_policy not in {\"fail_open\", \"raise\"}:\n            raise ValueError(\"OpenViking failure_policy.read must be 'fail_open' or 'raise'\")\n        if self.write_failure_policy not in {\"log_and_drop\", \"raise\"}:\n            raise ValueError(\"OpenViking failure_policy.write must be 'log_and_drop' or 'raise'\")\n        if not 16 <= self.max_seen_message_ids <= 10_000:\n            raise ValueError(\"OpenViking max_seen_message_ids must be between 16 and 10000\")\n\n\ndef is_safe_peer_id(value: str) -> bool:\n    \"\"\"Return whether *value* is valid for an OpenViking actor peer.\"\"\"\n\n    return _SAFE_PEER_RE.fullmatch(value) is not None\n\n\ndef _mapping(value: Any, name: str) -> dict[str, Any]:\n    if value is None:\n        return {}\n    if not isinstance(value, dict):\n        raise ValueError(f\"OpenViking {name} must be a mapping\")\n    return dict(value)\n\n\ndef _optional_float(value: Any) -> float | None:\n    return None if value is None else float(value)\n\n\ndef _boolean(value: Any, name: str) -> bool:\n    if isinstance(value, bool):\n        return value\n    if isinstance(value, str):\n        normalized = value.strip().lower()\n        if normalized in {\"true\", \"1\", \"yes\", \"on\"}:\n            return True\n        if normalized in {\"false\", \"0\", \"no\", \"off\"}:\n            return False\n    raise ValueError(f\"OpenViking {name} must be a boolean\")\n","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/bytedance/deer-flow/blob/1dd6ba1acb03700589994b0366c5d1c7d05e2eff/backend/packages/harness/deerflow/agents/memory/backends/openviking/config.py#L138-L174","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Make retrieval and failure_policy nested mappings in config.yaml: retrieval: {top_k: 8, ...}, failure_policy: {read: fail_open, write: log_and_drop}","Verify with a YAML linter that the section parses to a dict, not a scalar/list","Restart the Gateway after fixing config.yaml"],"exampleFix":"# before (config.yaml)\nmemory:\n  backend_config:\n    retrieval: 8\n\n# after\nmemory:\n  backend_config:\n    retrieval:\n      top_k: 8","handlingStrategy":"type-guard","validationCode":"for section in (\"retrieval\", \"failure_policy\"):\n    value = raw_backend_config.get(section)\n    assert value is None or isinstance(value, dict), f\"OpenViking {section} must be a mapping (dict), got {type(value).__name__}\"","typeGuard":"def is_mapping_section(value: object) -> bool:\n    return value is None or isinstance(value, dict)","tryCatchPattern":null,"preventionTips":["Parse config.yaml with a YAML linter that checks section shapes","Keep retrieval/failure_policy nested one level under backend_config","Add a config schema check (e.g. jsonschema or from_backend_config) to deployment preflight"],"tags":["openviking","config","yaml","validation"],"backgroundTag":null,"analyzedSha":"1dd6ba1acb03700589994b0366c5d1c7d05e2eff","analyzedAt":"2026-08-14T21:20:34.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}