HKUDS/Vibe-Trading · error · ValueError

Agent config must decode to a JSON/YAML object

Error message

Agent config must decode to a JSON/YAML object

What it means

Raised by _read_config_file when the parsed config file does not decode to a dict — e.g. the file contains a JSON array, scalar, or a YAML list/top-level scalar. The agent config schema requires a top-level object (mapping of settings).

Source

Thrown at agent/src/config/loader.py:258

    Raises:
        ValueError: If the file format is unsupported, YAML support is
            unavailable, or the decoded payload is not an object.
    """
    suffix = path.suffix.lower()
    text = path.read_text(encoding="utf-8")

    if suffix == ".json":
        data = json.loads(text)
    elif suffix in {".yaml", ".yml"}:
        if yaml is None:
            raise ValueError("YAML config is not available because PyYAML is missing")
        data = yaml.safe_load(text) or {}
    else:
        raise ValueError(f"Unsupported config file format: {suffix or '<none>'}")

    if not isinstance(data, dict):
        raise ValueError("Agent config must decode to a JSON/YAML object")
    return data


def _merge_agent_config_dicts(base: dict[str, Any], override: dict[str, Any]) -> dict[str, Any]:
    """Merge top-level agent config payloads with MCP-aware server replacement."""
    non_mcp_override = {key: value for key, value in override.items() if key != "mcp_servers"}
    merged = _merge_dicts(base, non_mcp_override)

    override_servers = override.get("mcp_servers")
    if not isinstance(override_servers, dict):
        if "mcp_servers" in override:
            merged["mcp_servers"] = override_servers
        return merged

    merged_servers = dict(base.get("mcp_servers", {}))
    for server_name, server_override in override_servers.items():
        current_server = merged_servers.get(server_name)
        if isinstance(current_server, dict) and isinstance(server_override, dict):

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Ensure the top-level structure of the config file is an object: { ... } in JSON or key: value mappings in YAML.
  2. Validate with a quick parse: python -c "import json;print(type(json.load(open('config.json'))))".
  3. Remove leading list dashes or wrapping brackets.

Example fix

// before
[{
  "model": "gpt"
}]

// after
{
  "model": "gpt"
}
Defensive patterns

Strategy: type-guard

Validate before calling

import json

def config_is_object(path: str) -> bool:
    with open(path) as f:
        return isinstance(json.load(f), dict)

Type guard

def is_config_dict(data) -> bool:
    return isinstance(data, dict)

Try / catch

try:
    data = _read_config_file(path)
except ValueError as e:
    if 'must decode to a JSON/YAML object' in str(e):
        raise ValueError(f'{path}: wrap the config in a top-level object {{...}}') from e
    raise

Prevention

When it happens

Trigger: A config.json that is [ ... ] or a bare string/number; a YAML file whose top level is a list; a YAML file containing only comments that safe_load treats as None combined with non-dict content.

Common situations: Hand-editing turned the object into an array; YAML with a stray '- ' on the first line making it a list; fragments copied from documentation examples that are arrays.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/a3d5d0c8ff272a74. Report an issue: GitHub.