HKUDS/Vibe-Trading · error · ValueError

flows must contain CashFlow, got {type(flow).__name__}

Error message

flows must contain CashFlow, got {type(flow).__name__}

What it means

translate_cashflows iterates flows and requires every member to be a CashFlow instance; dicts, tuples, or duck-typed objects fail with the type name before any currency math begins.

Source

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

            ``quote_currency`` becomes the returned series' currency.
        allow_stale_rates: Forwarded to ``FxRateTable.get_rate``. Off by
            default, so a settlement date with no exact quote raises rather
            than silently reusing an older one.
        max_staleness_days: Forwarded to ``FxRateTable.get_rate``.

    Returns:
        A ``CashFlowSeries`` with ``pre_translated=True`` and
        ``currency=rate_table.quote_currency``.

    Raises:
        MissingExchangeRateError: If a flow's currency has no usable rate for
            its settlement date; see ``allow_stale_rates``.
        ValueError: If ``flows`` contains a member that is not a ``CashFlow``.
    """
    translated: list[CashFlow] = []
    for flow in flows:
        if not isinstance(flow, CashFlow):
            raise ValueError(f"flows must contain CashFlow, got {type(flow).__name__}")

        if flow.currency == rate_table.quote_currency:
            converted_amount = flow.amount
            rate_used = 1.0
            rate_date = flow.date
            is_stale = False
        else:
            fx_rate, is_stale = rate_table.get_rate(
                flow.currency,
                flow.date,
                allow_stale=allow_stale_rates,
                max_staleness_days=max_staleness_days,
            )
            converted_amount = flow.amount * fx_rate.rate
            rate_used = fx_rate.rate
            rate_date = fx_rate.date

        metadata = dict(flow.metadata)

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Construct CashFlow objects first, then translate
  2. If rows come from a file, run the loader (load_cashflows) that produces entities

Example fix

# before
translated = table.translate_cashflows(raw_rows)
# after
flows = [CashFlow(**r) for r in raw_rows]
translated = table.translate_cashflows(flows)
Defensive patterns

Strategy: type-guard

Validate before calling

from agent.src.entities.cashflow import CashFlow
assert all(isinstance(f, CashFlow) for f in flows)

Type guard

from agent.src.entities.cashflow import CashFlow
def all_cashflows(seq) -> bool:
    return all(isinstance(f, CashFlow) for f in seq)

Try / catch

try:
    table.translate_cashflows(flows)
except ValueError as e:
    if 'must contain CashFlow' in str(e):
        flows = [f if isinstance(f, CashFlow) else CashFlow(**f) for f in flows]

Prevention

When it happens

Trigger: table.translate_cashflows([{'amount': 100, 'currency': 'EUR'}, ...]) — raw rows passed instead of entities.

Common situations: Piping loader output directly into translation without constructing CashFlow objects; pandas to_dict records; a test using stub objects.

Related errors


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