{"record":{"id":"259ad8629b4140d7","repo":"HKUDS/Vibe-Trading","slug":"export-comps-workbook-expected-a-comps-artifact","errorCode":null,"errorMessage":"export_comps_workbook: expected a 'comps' artifact, got {artifact.model_name!r}","messagePattern":"export_comps_workbook: expected a 'comps' artifact, got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/valuation/artifact.py","lineNumber":1314,"sourceCode":"\n    Sheets, in order: \"Peer Detail\", \"Multiple Matrix\" (including the\n    excluded-peer detail block), \"Implied Valuation\", \"Assumptions & Data\n    Quality\" (see :func:`_write_assumptions_and_gaps_sheet` -- for comps this\n    sheet's assumptions block always reads \"(none)\"; see\n    :func:`build_comps_artifact`).\n\n    Args:\n        artifact: A ``model_name=\"comps\"`` artifact from :func:`build_comps_artifact`.\n        path: Output ``.xlsx`` path. Parent directories are created if absent.\n\n    Returns:\n        The written path.\n\n    Raises:\n        TypeError: If ``artifact.model_name != \"comps\"``.\n    \"\"\"\n    if artifact.model_name != \"comps\":\n        raise TypeError(\n            f\"export_comps_workbook: expected a 'comps' artifact, got {artifact.model_name!r}\"\n        )\n    result: CompsResult = artifact.result\n\n    wb = Workbook()\n    wb.remove(wb.active)\n    _write_peer_detail_sheet(wb, result)\n    _write_multiple_matrix_sheet(wb, result)\n    _write_implied_valuation_sheet(wb, result)\n    _write_assumptions_and_gaps_sheet(wb, artifact)\n\n    out_path = Path(path)\n    out_path.parent.mkdir(parents=True, exist_ok=True)\n    wb.save(str(out_path))\n    return out_path\n\n\n# ---------------------------------------------------------------------------","sourceCodeStart":1296,"sourceCodeEnd":1332,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/valuation/artifact.py#L1296-L1332","documentation":"export_comps_workbook only accepts artifacts whose model_name is 'comps'; it casts artifact.result to CompsResult and writes the comps workbook. Any other model_name raises a TypeError up front.","triggerScenarios":"export_comps_workbook(dcf_artifact, path); feeding a three_statement artifact; a routing table pointing all artifacts at the comps exporter.","commonSituations":"Copy-pasted export call sites; generic export menus; refactored model_name strings after a rename.","solutions":["Use the exporter matching the artifact's model_name.","Dispatch on model_name (dict of exporters).","Rename/route checks before export."],"exampleFix":"# before\nexport_comps_workbook(artifact, path)  # artifact.model_name == \"dcf\"\n# after\nexport_dcf_workbook(artifact, path)  # or dispatch on artifact.model_name","handlingStrategy":"type-guard","validationCode":"if artifact.model_name != \"comps\":\n    raise TypeError(f\"not a comps artifact: {artifact.model_name!r}\")\nexport_comps_workbook(artifact, path)","typeGuard":"def is_comps_artifact(a) -> bool:\n    return getattr(a, \"model_name\", None) == \"comps\"","tryCatchPattern":null,"preventionTips":["Dispatch exporters by model_name.","Keep export functions model-specific; don't write generic wrappers that guess."],"tags":["python","excel","workbook","export","type-validation"],"backgroundTag":"wrong-artifact-type-for-export","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}