HKUDS/Vibe-Trading · error · ValueError

amount must be numeric, got {self.amount!r}

Error message

amount must be numeric, got {self.amount!r}

What it means

CashFlow.__post_init__ coerces the amount field to float; if float(self.amount) raises TypeError or ValueError, the conversion failure is re-raised as a ValueError with the offending repr. The library requires every cash flow's amount to be a number so arithmetic (sums, sign checks, FX translation) is well-defined.

Source

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

    currency: str
    metadata: Mapping[str, Any] = field(default_factory=dict)

    def __post_init__(self) -> None:
        """Normalize every field and enforce the sign convention.

        Raises:
            ValueError: If the date is unsupported, the amount is not finite,
                the currency or kind is blank, or the amount's sign contradicts
                a canonical kind in ``KIND_DIRECTION``.
        """
        object.__setattr__(self, "date", normalize_date(self.date))
        object.__setattr__(self, "kind", normalize_kind(self.kind))
        object.__setattr__(self, "currency", normalize_currency(self.currency))

        try:
            amount = float(self.amount)
        except (TypeError, ValueError) as exc:
            raise ValueError(
                f"amount must be numeric, got {self.amount!r}"
            ) from exc
        if not math.isfinite(amount):
            raise ValueError(
                f"amount must be a finite number, got {self.amount!r}; a missing "
                "value must be fixed at the source, not carried as NaN"
            )
        object.__setattr__(self, "amount", amount)

        required_sign = KIND_DIRECTION.get(self.kind)
        if required_sign is not None and amount != 0.0:
            if (amount > 0) != (required_sign > 0):
                direction = "positive (cash in)" if required_sign > 0 else "negative (cash out)"
                raise ValueError(
                    f"kind={self.kind!r} must have a {direction} amount under the "
                    f"holder-perspective sign convention, got {amount!r}. Flip the "
                    "sign, or use a distinct kind if this flow is genuinely "
                    "two-directional (e.g. 'recallable_distribution')."

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Coerce/parse the amount to a float before constructing CashFlow (strip separators/currency symbols, treat empty strings as missing data to fix upstream)
  2. Validate the source column at ingest time (e.g. a parse step in your loader) instead of at entity construction
  3. If the value is genuinely missing, fix or drop the row at the source rather than passing a placeholder string

Example fix

// before
CashFlow(date=d, kind='dividend', amount='1,234.56', currency='USD')
# after
CashFlow(date=d, kind='dividend', amount=1234.56, currency='USD')
Defensive patterns

Strategy: validation

Validate before calling

def to_amount(raw):
    try:
        value = float(raw)
    except (TypeError, ValueError):
        raise ValueError(f'unparseable amount: {raw!r}') from None
    return value

amounts_ok = all(isinstance(to_amount(r.get('amount')), float) for r in rows)

Type guard

def is_numeric_amount(v) -> bool:
    return isinstance(v, (int, float)) and not isinstance(v, bool)

Try / catch

try:
    flow = CashFlow(amount=raw, ...)
except ValueError as e:
    if 'amount must be numeric' in str(e):
        # log the row, skip or repair
        ...

Prevention

When it happens

Trigger: Constructing CashFlow with a non-numeric amount: CashFlow(amount='abc', ...), CashFlow(amount=None, ...), or a string like '1,234.56' that float() cannot parse.

Common situations: Rows loaded from CSV/Excel where the amount column has thousands separators, currency symbols, empty cells, or stray text; dataclass defaults left as None; pandas object-dtype values passed through unconverted.

Related errors


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