{"record":{"id":"01f2b2ffdbeb32c3","repo":"HKUDS/Vibe-Trading","slug":"run-card-path-or-backtest-run-dir-is-required","errorCode":null,"errorMessage":"run_card_path or backtest_run_dir is required","messagePattern":"run_card_path or backtest_run_dir is required","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/hypotheses/registry.py","lineNumber":312,"sourceCode":"        Args:\n            hypothesis_id: Registry identifier.\n            run_card_path: Optional path to a run_card.json.\n            backtest_run_dir: Optional backtest run directory.\n            metrics: Optional metrics summary.\n            validation: Optional walk-forward/Monte-Carlo/bootstrap robustness\n                results, as written by write_run_card's top-level\n                \"validation\" key (a sibling of \"metrics\", not nested in it).\n            notes: Optional human note about the link.\n\n        Returns:\n            Updated hypothesis.\n\n        Raises:\n            KeyError: If the hypothesis does not exist.\n            ValueError: If no run card or run directory is provided.\n        \"\"\"\n        if not run_card_path and not backtest_run_dir:\n            raise ValueError(\"run_card_path or backtest_run_dir is required\")\n        records = self.list()\n        hyp = self._find_required(records, hypothesis_id)\n        run_card_record: dict[str, Any] = {\n            \"run_card_path\": run_card_path,\n            \"backtest_run_dir\": backtest_run_dir,\n            \"metrics\": metrics or {},\n            \"notes\": notes,\n            \"linked_at\": _utc_now(),\n        }\n        if validation is not None:\n            run_card_record[\"validation\"] = validation\n        hyp.run_cards.append(run_card_record)\n        hyp.updated_at = _utc_now()\n        self._save(records)\n        return hyp\n\n    def search(\n        self,","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/hypotheses/registry.py#L294-L330","documentation":"HypothesisRegistry.link_backtest requires at least one of run_card_path or backtest_run_dir to identify the backtest being attached to a hypothesis. Both defaulting to empty/None means there is nothing to link, so the call is rejected before mutation.","triggerScenarios":"Calling link_backtest(hid, run_card_path=None, backtest_run_dir=None), or passing '' for both because the backtest job failed to produce a run card path.","commonSituations":"Linking a hypothesis to a backtest run whose artifacts weren't generated (job crashed), or wiring up the call before the path variables are populated.","solutions":["Pass the run card file path produced by the backtest executor","Or pass the backtest run directory if no single run card exists","Guard the call: only link after confirming the backtest produced a path/dir"],"exampleFix":"# before\nregistry.link_backtest(hid)\n# after\nregistry.link_backtest(hid, run_card_path=run.run_card_path)","handlingStrategy":"validation","validationCode":"if not (run_card_path or backtest_run_dir):\n    raise ValueError('nothing to link: backtest produced no artifacts')\nregistry.link_backtest(hid, run_card_path=run_card_path, backtest_run_dir=backtest_run_dir)","typeGuard":"def has_link_target(rc, rd) -> bool:\n    return bool(str(rc or '').strip() or str(rd or '').strip())","tryCatchPattern":"try:\n    registry.link_backtest(hid, run_card_path=rc)\nexcept ValueError as exc:\n    if 'required' in str(exc):\n        log.warning('skipping link for %s: no run artifacts', hid)","preventionTips":["Only call link_backtest after confirming the backtest emitted a run card or run dir","Treat missing artifacts as a failed backtest, not an empty link","Assert path existence before linking"],"tags":["python","validation","required-argument","backtest"],"backgroundTag":"missing-required-argument","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}