{"record":{"id":"118937db58c5401e","repo":"HKUDS/Vibe-Trading","slug":"comps-run-comps-mixed-eps-basis-across-the-comp-s","errorCode":null,"errorMessage":"comps.run_comps: mixed eps_basis across the comp set {sorted(all_bases)} -- every peer and the target must declare the same EPS basis, or the P/E distribution mixes GAAP and adjusted earnings","messagePattern":"comps\\.run_comps: mixed eps_basis across the comp set (.+?) -- every peer and the target must declare the same EPS basis, or the P/E distribution mixes GAAP and adjusted earnings","errorType":"exception","errorClass":"ValuationError","httpStatus":null,"severity":"error","filePath":"agent/src/quantlib/valuation/comps.py","lineNumber":1182,"sourceCode":"        MissingInputError: (propagated from `calendarise_metric`) if any\n            peer's or the target's fiscal-period data lacks a field\n            `calendarisation_policy` needs.\n    \"\"\"\n    if calendarisation_policy not in CALENDARISATION_POLICIES:\n        raise ValuationError(\n            f\"comps.run_comps: unknown calendarisation_policy {calendarisation_policy!r}, \"\n            f\"must be one of {CALENDARISATION_POLICIES}\"\n        )\n    if len(peers) == 0:\n        raise MissingInputError((\"peers\",), \"comps.run_comps\")\n\n    names = [peer.name for peer in peers]\n    if len(set(names)) != len(names):\n        raise ValuationError(f\"comps.run_comps: duplicate peer names in {names}\")\n\n    all_bases = {peer.eps_basis for peer in peers} | {target.eps_basis}\n    if len(all_bases) > 1:\n        raise ValuationError(\n            \"comps.run_comps: mixed eps_basis across the comp set \"\n            f\"{sorted(all_bases)} -- every peer and the target must declare the \"\n            \"same EPS basis, or the P/E distribution mixes GAAP and adjusted \"\n            \"earnings\"\n        )\n\n    peer_multiples = tuple(peer_multiple_set(peer, calendarisation_policy) for peer in peers)\n    distributions = {\n        name: multiple_distribution(name, peer_multiples) for name in MULTIPLE_NAMES\n    }\n\n    calendarised_target = {\n        \"ebitda\": calendarise_metric(\n            target.ebitda, calendarisation_policy, metric_name=\"ebitda\", company_name=target.name\n        ),\n        \"ebit\": calendarise_metric(\n            target.ebit, calendarisation_policy, metric_name=\"ebit\", company_name=target.name\n        ),","sourceCodeStart":1164,"sourceCodeEnd":1200,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/quantlib/valuation/comps.py#L1164-L1200","documentation":"Every peer and the target must declare the same eps_basis; mixing basic and diluted EPS across the comp set would make the P/E distribution compare GAAP and adjusted figures inconsistently, so run_comps refuses the mixture.","triggerScenarios":"One peer dataclass built with eps_basis='basic' while target/others use 'diluted' — often one row built by different code or a defaulted constructor call.","commonSituations":"Heterogeneous data ingestion where one vendor reports basic EPS only; a peer added later with a default basis; copy-pasted fixture code diverging from the production path.","solutions":["Standardize: pick one basis (usually diluted) and rebuild all peers/target with it explicitly.","If a vendor only has basic EPS, convert or document the choice rather than mixing.","Assert {p.eps_basis for p in peers} | {target.eps_basis} has exactly one element before run_comps."],"exampleFix":"# before\npeers = [CompPeer('A','diluted',...), CompPeer('B','basic',...)]\n\n# after\nfrom dataclasses import replace\npeers = [replace(p, eps_basis='diluted') for p in peers]  # after verifying data supports it","handlingStrategy":"validation","validationCode":"bases = {p.eps_basis for p in peers} | {target.eps_basis}\nif len(bases) > 1:\n    raise ValueError(f'mixed eps_basis: {sorted(bases)}')","typeGuard":"def uniform_eps_basis(target, peers):\n    return len({p.eps_basis for p in peers} | {target.eps_basis}) == 1","tryCatchPattern":"except ValuationError as e:\n    if 'mixed eps_basis' in str(e):\n        peers = [replace(p, eps_basis='diluted') for p in peers]","preventionTips":["Set eps_basis explicitly at every construction site","Standardize on one basis in the ingestion contract"],"tags":["valuation","eps-basis","consistency","comps"],"backgroundTag":"inconsistent-config-values","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}