HKUDS/Vibe-Trading · error · ValueError

rates must contain FxRate, got {type(entry).__name__}

Error message

rates must contain FxRate, got {type(entry).__name__}

What it means

FxRateTable.from_rates iterates the input and requires every element to be an FxRate; anything else (dicts, floats, tuples from a parsed feed) fails with the type name before indexing by (base_currency, date).

Source

Thrown at agent/src/entities/cashflow.py:573

    def from_rates(cls, rates: Iterable[FxRate], *, quote_currency: str) -> "FxRateTable":
        """Build a table from a sequence of individual quotes.

        Args:
            rates: The quotes, all against ``quote_currency``.
            quote_currency: The reporting currency of the table.

        Returns:
            A new ``FxRateTable`` keyed by ``(base_currency, date)``.

        Raises:
            ValueError: If a member is not an ``FxRate``, two quotes collide
                on the same ``(base_currency, date)`` with different rates,
                or a quote's ``quote_currency`` disagrees with the table's.
        """
        indexed: dict[tuple[str, date], FxRate] = {}
        for entry in rates:
            if not isinstance(entry, FxRate):
                raise ValueError(f"rates must contain FxRate, got {type(entry).__name__}")
            key = (entry.base_currency, entry.date)
            if key in indexed and indexed[key].rate != entry.rate:
                raise ValueError(
                    f"conflicting rates for {key}: {indexed[key].rate!r} vs "
                    f"{entry.rate!r}"
                )
            indexed[key] = entry
        return cls(quote_currency=quote_currency, rates=indexed)

    @classmethod
    def from_mapping(
        cls,
        mapping: Mapping[tuple[str, "date | datetime | str"], float],
        *,
        quote_currency: str,
    ) -> "FxRateTable":
        """Build a table from ``{(base_currency, date): rate}`` pairs.

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Convert each row to FxRate(base_currency, quote_currency, date, rate) before calling from_rates
  2. If rows come from a mapping format, use from_mapping, which performs the conversion

Example fix

# before
FxRateTable.from_rates(rows, quote_currency='USD')  # rows are dicts
# after
rates = [FxRate(r['base'], 'USD', parse_date(r['date']), float(r['rate'])) for r in rows]
table = FxRateTable.from_rates(rates, quote_currency='USD')
Defensive patterns

Strategy: type-guard

Validate before calling

from agent.src.entities.cashflow import FxRate
assert all(isinstance(r, FxRate) for r in rates)

Type guard

from agent.src.entities.cashflow import FxRate
def all_fx_rates(seq) -> bool:
    return all(isinstance(r, FxRate) for r in seq)

Try / catch

try:
    table = FxRateTable.from_rates(rates, quote_currency=q)
except ValueError as e:
    if 'must contain FxRate' in str(e):
        rates = [FxRate(r['base'], q, parse(r['date']), float(r['rate'])) for r in rates]

Prevention

When it happens

Trigger: FxRateTable.from_rates([{'base':'EUR','rate':1.08}, ...], quote_currency='USD') or a list of (base, date, rate) tuples.

Common situations: Feeding raw rows from a rates API or CSV straight into from_rates; passing pandas itertuples() results; test fixtures with placeholder tuples.

Related errors


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