{"record":{"id":"a3d5d0c8ff272a74","repo":"HKUDS/Vibe-Trading","slug":"agent-config-must-decode-to-a-json-yaml-object","errorCode":null,"errorMessage":"Agent config must decode to a JSON/YAML object","messagePattern":"Agent config must decode to a JSON/YAML object","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/config/loader.py","lineNumber":258,"sourceCode":"\n    Raises:\n        ValueError: If the file format is unsupported, YAML support is\n            unavailable, or the decoded payload is not an object.\n    \"\"\"\n    suffix = path.suffix.lower()\n    text = path.read_text(encoding=\"utf-8\")\n\n    if suffix == \".json\":\n        data = json.loads(text)\n    elif suffix in {\".yaml\", \".yml\"}:\n        if yaml is None:\n            raise ValueError(\"YAML config is not available because PyYAML is missing\")\n        data = yaml.safe_load(text) or {}\n    else:\n        raise ValueError(f\"Unsupported config file format: {suffix or '<none>'}\")\n\n    if not isinstance(data, dict):\n        raise ValueError(\"Agent config must decode to a JSON/YAML object\")\n    return data\n\n\ndef _merge_agent_config_dicts(base: dict[str, Any], override: dict[str, Any]) -> dict[str, Any]:\n    \"\"\"Merge top-level agent config payloads with MCP-aware server replacement.\"\"\"\n    non_mcp_override = {key: value for key, value in override.items() if key != \"mcp_servers\"}\n    merged = _merge_dicts(base, non_mcp_override)\n\n    override_servers = override.get(\"mcp_servers\")\n    if not isinstance(override_servers, dict):\n        if \"mcp_servers\" in override:\n            merged[\"mcp_servers\"] = override_servers\n        return merged\n\n    merged_servers = dict(base.get(\"mcp_servers\", {}))\n    for server_name, server_override in override_servers.items():\n        current_server = merged_servers.get(server_name)\n        if isinstance(current_server, dict) and isinstance(server_override, dict):","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/config/loader.py#L240-L276","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the top-level structure of the config file is an object: { ... } in JSON or key: value mappings in YAML.","Validate with a quick parse: python -c \"import json;print(type(json.load(open('config.json'))))\".","Remove leading list dashes or wrapping brackets."],"exampleFix":"// before\n[{\n  \"model\": \"gpt\"\n}]\n\n// after\n{\n  \"model\": \"gpt\"\n}","handlingStrategy":"type-guard","validationCode":"import json\n\ndef config_is_object(path: str) -> bool:\n    with open(path) as f:\n        return isinstance(json.load(f), dict)","typeGuard":"def is_config_dict(data) -> bool:\n    return isinstance(data, dict)","tryCatchPattern":"try:\n    data = _read_config_file(path)\nexcept ValueError as e:\n    if 'must decode to a JSON/YAML object' in str(e):\n        raise ValueError(f'{path}: wrap the config in a top-level object {{...}}') from e\n    raise","preventionTips":["Lint config files in CI with a JSON/YAML schema check","Start from a provided example config object rather than from scratch"],"tags":["config","json","yaml","schema-validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}