{"record":{"id":"07da8835efeee7b3","repo":"HKUDS/Vibe-Trading","slug":"hypotheses-storage-must-contain-a-json-list","errorCode":null,"errorMessage":"hypotheses storage must contain a JSON list","messagePattern":"hypotheses storage must contain a JSON list","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"agent/src/hypotheses/registry.py","lineNumber":376,"sourceCode":"                score = 1\n            else:\n                hay_tokens = _tokenize(haystack)\n                score = len(query_tokens & hay_tokens)\n            if score > 0:\n                scored.append((score, hyp))\n        scored.sort(key=lambda item: (item[0], item[1].updated_at), reverse=True)\n        return [hyp for _, hyp in scored[: max(1, min(int(limit), 100))]]\n\n    def list(self) -> list[Hypothesis]:\n        \"\"\"Load all hypotheses from storage.\"\"\"\n        if not self.path.exists():\n            return []\n        try:\n            raw = json.loads(self.path.read_text(encoding=\"utf-8\"))\n        except json.JSONDecodeError as exc:\n            raise ValueError(f\"invalid hypotheses storage JSON: {self.path}\") from exc\n        if not isinstance(raw, list):\n            raise ValueError(\"hypotheses storage must contain a JSON list\")\n        return [Hypothesis.from_dict(item) for item in raw if isinstance(item, dict)]\n\n    def _save(self, records: list[Hypothesis]) -> None:\n        payload = [hyp.to_dict() for hyp in sorted(records, key=lambda h: h.created_at)]\n        tmp_path = self.path.with_suffix(self.path.suffix + \".tmp\")\n        tmp_path.write_text(\n            json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True),\n            encoding=\"utf-8\",\n        )\n        tmp_path.replace(self.path)\n\n    @staticmethod\n    def _find_required(records: list[Hypothesis], hypothesis_id: str) -> Hypothesis:\n        for hyp in records:\n            if hyp.hypothesis_id == hypothesis_id:\n                return hyp\n        raise KeyError(f\"hypothesis not found: {hypothesis_id}\")\n","sourceCodeStart":358,"sourceCodeEnd":394,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/hypotheses/registry.py#L358-L394","documentation":"The hypotheses storage file parses as valid JSON but its top-level value is not an array (e.g. an object, string, or number). The storage schema requires a JSON list of hypothesis objects, so loading aborts.","triggerScenarios":"The file contains {\"hypotheses\": [...]} instead of [...], or a single hypothesis object at the root; then list() and every mutating method fail.","commonSituations":"Someone reshaped the file by hand, or an export tool wrote an object wrapper; schema drift after a version change of the registry format.","solutions":["Rewrap the content as a top-level JSON array of hypothesis objects","If a wrapper object exists, extract the inner list into the root","Validate the file shape after any manual or external-tool edit"],"exampleFix":"# before (file content)\n{\"hypotheses\": [{\"hypothesis_id\": \"h1\", ...}]}\n# after\n[{\"hypothesis_id\": \"h1\", ...}]","handlingStrategy":"type-guard","validationCode":"raw = json.loads(path.read_text(encoding='utf-8'))\nif not isinstance(raw, list):\n    raw = raw.get('hypotheses', []) if isinstance(raw, dict) else []\n    path.write_text(json.dumps(raw), encoding='utf-8')","typeGuard":"def is_storage_list(raw) -> bool:\n    return isinstance(raw, list) and all(isinstance(i, dict) for i in raw)","tryCatchPattern":"try:\n    records = registry.list()\nexcept ValueError as exc:\n    if 'must contain a JSON list' in str(exc):\n        rewrite_storage_as_list()  # migration/repair\n    else:\n        raise","preventionTips":["Validate the file shape after any external tool writes it","Version the storage schema and run migrations on load","Don't restructure the file format by hand"],"tags":["python","json","schema","persistence"],"backgroundTag":"json-schema-mismatch","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}