HKUDS/Vibe-Trading · error · ValuationError

comps.run_comps: duplicate peer names in {names}

Error message

comps.run_comps: duplicate peer names in {names}

What it means

run_comps rejects a peer list containing duplicate names. Peer names are the identity used for reporting, exclusion lists, and cross-referencing, so two peers with the same name would silently overwrite/confuse results.

Source

Thrown at agent/src/quantlib/valuation/comps.py:1178

            the same `eps_basis` (mixing GAAP and adjusted EPS across the
            comp set would skew the P/E distribution by whatever one-time
            items the adjustment removes, the same kind of silent distortion
            the calendarisation-policy rule exists to prevent).
        MissingInputError: (propagated from `calendarise_metric`) if any
            peer's or the target's fiscal-period data lacks a field
            `calendarisation_policy` needs.
    """
    if calendarisation_policy not in CALENDARISATION_POLICIES:
        raise ValuationError(
            f"comps.run_comps: unknown calendarisation_policy {calendarisation_policy!r}, "
            f"must be one of {CALENDARISATION_POLICIES}"
        )
    if len(peers) == 0:
        raise MissingInputError(("peers",), "comps.run_comps")

    names = [peer.name for peer in peers]
    if len(set(names)) != len(names):
        raise ValuationError(f"comps.run_comps: duplicate peer names in {names}")

    all_bases = {peer.eps_basis for peer in peers} | {target.eps_basis}
    if len(all_bases) > 1:
        raise ValuationError(
            "comps.run_comps: mixed eps_basis across the comp set "
            f"{sorted(all_bases)} -- every peer and the target must declare the "
            "same EPS basis, or the P/E distribution mixes GAAP and adjusted "
            "earnings"
        )

    peer_multiples = tuple(peer_multiple_set(peer, calendarisation_policy) for peer in peers)
    distributions = {
        name: multiple_distribution(name, peer_multiples) for name in MULTIPLE_NAMES
    }

    calendarised_target = {
        "ebitda": calendarise_metric(
            target.ebitda, calendarisation_policy, metric_name="ebitda", company_name=target.name

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Dedupe by name (or a canonical identifier) before calling run_comps.
  2. If two entries are genuinely distinct companies, disambiguate names (e.g. append ticker or country).
  3. Check for the same ticker appearing twice in the input universe.

Example fix

# before
peers = vendor_a_peers + vendor_b_peers  # dupes

# after
seen = set()
peers = [p for p in vendor_a_peers + vendor_b_peers if not (p.name in seen or seen.add(p.name))]
Defensive patterns

Strategy: validation

Validate before calling

names = [p.name for p in peers]
if len(set(names)) != len(names):
    raise ValueError(f'duplicate peer names: {sorted(names)}')

Type guard

def no_duplicate_names(peers):
    names = [p.name for p in peers]
    return len(set(names)) == len(names)

Try / catch

except ValuationError as e:
    if 'duplicate peer names' in str(e):
        peers = dedupe_by_name(peers)
        result = run_comps(target, peers)

Prevention

When it happens

Trigger: Passing peers=[CompPeer(name='Apple',...), CompPeer(name='Apple',...)] — e.g. the same company fetched from two sources, or name collisions after normalization.

Common situations: Merging peer lists from multiple vendors without deduping; two share classes of one company mapped to the same display name; retries appending duplicates.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/9792932cf5460ee2. Report an issue: GitHub.