HKUDS/Vibe-Trading · error · ValueError
manifest file {manifest_path} must be a JSON object with a '
Error message
manifest file {manifest_path} must be a JSON object with a 'runs' array or a bare JSON array of run specs What it means
After parsing, load_manifest expects either a bare JSON array of run specs or a JSON object containing a 'runs' key whose value is a list. This variant fires when the top level is a dict but parsed['runs'] is not a list — e.g. it's missing, an object, a string, or null. The runs list is what gets returned for validation.
Source
Thrown at agent/src/tools/strategy_discovery_tool.py:483
raw = manifest_path.read_text(encoding="utf-8")
except OSError as exc:
raise ValueError(
f"manifest file {manifest_path} is missing or unreadable "
f"({exc.strerror or 'I/O error'})"
) from exc
try:
parsed = json.loads(raw)
except json.JSONDecodeError as exc:
raise ValueError(
f"manifest file {manifest_path} is not valid JSON: {exc.msg} "
f"at line {exc.lineno} column {exc.colno}"
) from exc
if isinstance(parsed, list):
return parsed
if isinstance(parsed, dict):
runs = parsed.get("runs")
if not isinstance(runs, list):
raise ValueError(
f"manifest file {manifest_path} must be a JSON object with a "
"'runs' array or a bare JSON array of run specs"
)
return runs
raise ValueError(
f"manifest file {manifest_path} must be a JSON object with a 'runs' "
"array or a bare JSON array of run specs"
)
def validate_refresh_entries(
entries: list,
) -> tuple[list[dict], list[dict]]:
"""Split raw manifest entries into rebuild-ready specs and skip records.
Per-entry validation (plan §4.6/D7): the entry must be a mapping with a
non-empty ``strategy_id`` (capped at ``_MAX_STRING_PARAM_CHARS``) and a
non-empty ``run_dir`` that resolves (expanduser + resolve) inside theView on GitHub (pinned to 80ffdda44c)
Solutions
- Rename the key to exactly "runs" and make its value a JSON array
- If runs are keyed by id (object), flatten to a list: {"runs": list(your_dict.values())} or [your_dict[k] for k in sorted(your_dict)]
- Check the tool's run-spec schema/docs for the expected manifest shape
Example fix
# before
{ "runs": { "r1": {"path": "..."}, "r2": {"path": "..."} } }
# after
{ "runs": [ {"path": "..."}, {"path": "..."} ] } Defensive patterns
Strategy: validation
Validate before calling
import json
data = json.loads(Path(manifest_path).read_text(encoding="utf-8"))
runs = data if isinstance(data, list) else data.get("runs") if isinstance(data, dict) else None
if not isinstance(runs, list):
raise ValueError("manifest must be a list or {'runs': [...]}")
core(manifest_path=manifest_path, ...) Type guard
def has_valid_runs_shape(data) -> bool:
return isinstance(data, list) or (isinstance(data, dict) and isinstance(data.get("runs"), list)) Prevention
- Use the documented {"runs": [...]} shape in manifest writers
- Flatten id-keyed run dicts to arrays before writing the manifest
When it happens
Trigger: Manifest like {"results": [...]} (wrong key), {"runs": {"a": 1}} (object not array), or {"runs": null}; any dict whose 'runs' value fails isinstance(runs, list).
Common situations: Schema drift between manifest writers and readers (key renamed to 'experiments'); wrapping run specs in a nested object for grouping; exporting from a tool that emits runs as a dict keyed by run id.
Related errors
- manifest path {manifest_path} could not be resolved: {exc}
- manifest path {manifest_path} is outside the runtime root an
- manifest file {manifest_path} is missing or unreadable ({exc
- manifest file {manifest_path} is not valid JSON: {exc.msg} a
- Agent config must decode to a JSON/YAML object
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/c65e47a88257ce49.
Report an issue: GitHub.