{"record":{"id":"037f1a0cbf463d16","repo":"HKUDS/Vibe-Trading","slug":"export-dcf-workbook-expected-a-dcf-artifact-go","errorCode":null,"errorMessage":"export_dcf_workbook: expected a 'dcf' artifact, got {artifact.model_name!r}","messagePattern":"export_dcf_workbook: expected a 'dcf' artifact, got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/valuation/artifact.py","lineNumber":1193,"sourceCode":"    value per share), \"Sensitivity\" (the caller-supplied grid), \"Assumptions\n    & Data Quality\" (see :func:`_write_assumptions_and_gaps_sheet`).\n\n    Args:\n        artifact: A ``model_name=\"dcf\"`` artifact from :func:`build_dcf_artifact`.\n        path: Output ``.xlsx`` path. Parent directories are created if absent.\n        sensitivity_grid: A wacc x growth value-per-share grid, e.g. from\n            :func:`src.quantlib.valuation.dcf.sensitivity_grid`. Required --\n            this function does not choose a WACC/growth sweep range on the\n            caller's behalf; see the module docstring.\n\n    Returns:\n        The written path.\n\n    Raises:\n        TypeError: If ``artifact.model_name != \"dcf\"``.\n    \"\"\"\n    if artifact.model_name != \"dcf\":\n        raise TypeError(\n            f\"export_dcf_workbook: expected a 'dcf' artifact, got {artifact.model_name!r}\"\n        )\n    result: DCFResult = artifact.result\n\n    wb = Workbook()\n    wb.remove(wb.active)\n    _write_fcff_bridge_sheet(wb, result)\n    _write_wacc_sheet(wb, result)\n    _write_terminal_value_sheet(wb, result)\n    _write_sensitivity_sheet(wb, sensitivity_grid)\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","sourceCodeStart":1175,"sourceCodeEnd":1211,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/valuation/artifact.py#L1175-L1211","documentation":"export_dcf_workbook dispatches on artifact.model_name and only accepts 'dcf'. It then assumes artifact.result is a DCFResult when building the Excel workbook, so any other model_name is a TypeError before touching openpyxl.","triggerScenarios":"export_dcf_workbook(comps_artifact, path); passing a three_statement artifact; wiring a generic artifact list into a DCF-only export function.","commonSituations":"Generic export loops/routing tables mapping artifacts to the wrong exporter; UI selecting the wrong workbook template.","solutions":["Call export_comps_workbook or export_three_statement_workbook for those model types.","Route by model_name in a dispatch dict.","Validate model_name before choosing the exporter."],"exampleFix":"# before\nexport_dcf_workbook(artifact, path)  # artifact.model_name == \"comps\"\n# after\nexporters = {\"dcf\": export_dcf_workbook, \"comps\": export_comps_workbook,\n             \"three_statement\": export_three_statement_workbook}\nexporters[artifact.model_name](artifact, path)","handlingStrategy":"type-guard","validationCode":"if artifact.model_name != \"dcf\":\n    raise TypeError(f\"not a dcf artifact: {artifact.model_name!r}\")\nexport_dcf_workbook(artifact, path)","typeGuard":"def is_dcf_artifact(a) -> bool:\n    return getattr(a, \"model_name\", None) == \"dcf\"","tryCatchPattern":null,"preventionTips":["Route exports through a {model_name: exporter} dispatch table.","Never reuse one model's export call site for another model's artifacts."],"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"}