HKUDS/Vibe-Trading · error · ValueError

FxRate stored under key {key!r} does not match its own (base

Error message

FxRate stored under key {key!r} does not match its own (base_currency, date) = {expected_key!r}

What it means

FxRateTable's rates mapping must be keyed by each entry's own (base_currency, date). A key that doesn't match the entry's fields would make lookups return the wrong rate, so construction fails with both the stored key and the expected key.

Source

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

                match its own ``(base_currency, date)``.
        """
        quote = normalize_currency(self.quote_currency, field_name="quote_currency")
        rates = dict(self.rates)
        for key, entry in rates.items():
            if not isinstance(entry, FxRate):
                raise ValueError(
                    f"FxRateTable entries must be FxRate, got {type(entry).__name__}"
                )
            if entry.quote_currency != quote:
                raise ValueError(
                    f"FxRate {entry.base_currency}/{entry.quote_currency}@"
                    f"{entry.date} does not quote against this table's "
                    f"currency {quote!r}; a table may only hold rates quoted "
                    "against one reporting currency"
                )
            expected_key = (entry.base_currency, entry.date)
            if key != expected_key:
                raise ValueError(
                    f"FxRate stored under key {key!r} does not match its own "
                    f"(base_currency, date) = {expected_key!r}"
                )
        object.__setattr__(self, "quote_currency", quote)
        object.__setattr__(self, "rates", MappingProxyType(rates))

    @classmethod
    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:

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Key by (entry.base_currency, entry.date) exactly
  2. Or avoid manual keying entirely: pass a flat iterable to FxRateTable.from_rates, which computes the keys

Example fix

# before
FxRateTable(quote_currency='USD', rates={('EUR', d2): FxRate('EUR','USD',d1,1.0850)})
# after
table = FxRateTable.from_rates([FxRate('EUR','USD',d1,1.0850)], quote_currency='USD')
Defensive patterns

Strategy: validation

Validate before calling

indexed = {(e.base_currency, e.date): e for e in rate_entries}
table = FxRateTable(quote_currency=q, rates=indexed)

Try / catch

try:
    FxRateTable(...)
except ValueError as e:
    if 'does not match its own' in str(e):
        re-key by (entry.base_currency, entry.date) and retry

Prevention

When it happens

Trigger: FxRateTable(quote_currency='USD', rates={('EUR', wrong_date): FxRate('EUR','USD',right_date,1.0850)}).

Common situations: Hand-building the dict and letting keys drift from entry dates (e.g. normalizing dates only on the value side); copying entries between tables while re-keying for a different period.

Related errors


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