validate_dcf.py: WACC band check never runs — Workbook has no .get(), so a 35% WACC returns PASS

Author: AB2006-personalCreated Sep 1, 2026Updated Sep 1, 2026

Summary

skills/dcf-model/scripts/validate_dcf.py line 163 calls .get() on an openpyxl.Workbook. That class does not define .get(), so the call raises AttributeError on every invocation. It is caught by the broad except Exception at the end of _check_wacc_range, which downgrades it to the warning "Could not validate WACC range".

Net effect: the 5–20% WACC band the script advertises is never checked, for any model, ever. A validator that cannot fail is indistinguishable from one that passes.

python
# line 163
wacc_sheet = self.workbook_values.get('WACC') or self.workbook_values['DCF']

Reproduce

python
import openpyxl
wb = openpyxl.Workbook(); ws = wb.active; ws.title = "DCF"
ws["A1"], ws["B1"] = "Terminal Growth Rate", 0.02
ws["A2"], ws["B2"] = "WACC", 0.35          # 35% — far outside the 5–20% band
ws["A3"], ws["B3"] = "PV of Terminal Value", 600
ws["A4"], ws["B4"] = "Enterprise Value", 1000
wb.create_sheet("WACC"); wb.create_sheet("Sensitivity")
wb.save("badwacc.xlsx")
$ python validate_dcf.py badwacc.xlsx
{
  "status": "PASS",
  "warnings": ["Could not validate WACC range: 'Workbook' object has no attribute 'get'"]
}

A 35% WACC returns PASS. Confirmed on openpyxl 3.1.5: hasattr(openpyxl.Workbook(), 'get') is False.

Suggested fix

python
# Workbook has no .get(); test membership in sheetnames.
if 'WACC' in self.workbook_values.sheetnames:
    wacc_sheet = self.workbook_values['WACC']
else:
    wacc_sheet = self.workbook_values['DCF']

Worth noting: a named sheet can exist and be empty. If a template creates a blank WACC sheet while the value lives on DCF, the lookup above binds the empty sheet and stops. Searching candidate sheets in order until a value is found is more robust.

The broad except Exception is what let this survive undetected — narrowing it, or logging the exception type, would surface the next one immediately.

Scope

Three identical copies on main:

  • plugins/vertical-plugins/financial-analysis/skills/dcf-model/scripts/validate_dcf.py
  • plugins/agent-plugins/pitch-agent/skills/dcf-model/scripts/validate_dcf.py
  • plugins/agent-plugins/model-builder/skills/dcf-model/scripts/validate_dcf.py

Found by running the bundled scripts against fixtures with planted defects. Happy to open a PR if useful.

Source: anthropics/financial-services