HKUDS/Vibe-Trading · error · CashFlowIngestError

{path} row {row_number}: amount {raw!r} is not usable: {exc}

Error message

{path} row {row_number}: amount {raw!r} is not usable: {exc}

What it means

Raised by _parse_amount when the amount cell cannot be converted to a float after normalization; the inner exception text describes the exact problem (e.g. leftover symbols, letters, or malformed grouping). The raw cell content is included for diagnosis.

Source

Thrown at agent/src/entities/ingest.py:220

    """
    text = (raw or "").strip()
    if not text:
        raise CashFlowIngestError(
            f"{path} row {row_number}: amount is blank. A missing amount must be "
            "fixed at the source; it is not treated as zero."
        )

    negative = text.startswith("(") and text.endswith(")")
    if negative:
        text = text[1:-1]
    text = "".join(ch for ch in text if ch not in _AMOUNT_SYMBOLS).strip()
    if text.endswith("-"):  # trailing-minus exports
        text = "-" + text[:-1]

    try:
        value = float(_to_plain_number(text, decimal_separator))
    except ValueError as exc:
        raise CashFlowIngestError(
            f"{path} row {row_number}: amount {raw!r} is not usable: {exc}"
        ) from exc
    return -value if negative else value


def _parse_date(
    raw: str,
    date_format: str | None,
    path: Path,
    row_number: int,
) -> date:
    """Parse a date cell, using an explicit format when one is supplied.

    Args:
        raw: Raw cell text.
        date_format: ``strptime`` format, or ``None`` to require ISO-8601.
        path: File path, used only for error messages.
        row_number: 1-based data row number, used only for error messages.

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Look at the raw value in the message and the inner exc text; strip non-numeric decoration in the source or a preprocessing pass
  2. Fix malformed values such as double dots or stray characters at the source
  3. If values use a locale format, also pass decimal_separator appropriately
  4. Add a pre-load cleaning step (regex strip of currency symbols/spaces) before load_cashflows

Example fix

# before: cell is 'USD 1,234.56'
load_cashflows('flows.csv')
# after: clean the column in the source, or preprocess:
import re
rows = [(d, re.sub(r'[^0-9.,()-]', '', a), c) for d, a, c in rows]
Defensive patterns

Strategy: try-catch

Validate before calling

import re
AMOUNT_OK = re.compile(r'^\(?-?[0-9][0-9.,]*-?\)?$')
bad = [(i, r[amount_col]) for i, r in enumerate(rows, 2) if not AMOUNT_OK.match((r[amount_col] or '').strip())]

Type guard

def looks_like_amount(text: str) -> bool:
    t = (text or '').strip().strip('()')
    return bool(re.fullmatch(r'-?[0-9][0-9.,]*', t))

Try / catch

try:
    load_cashflows(p)
except CashFlowIngestError as e:
    if 'is not usable' in str(e):
        row = extract_row_number(e); log_defect(row, e); quarantine(p, row)

Prevention

When it happens

Trigger: An amount cell like 'USD 100', '1.2.3', 'abc', '(12,34' (unbalanced parentheses leave stray characters), or a trailing-minus form that still fails float() after _to_plain_number processing, passed through load_cashflows/_parse_panel_amount.

Common situations: Exports that embed currency codes or footnote markers in the amount column; copy-pasted spreadsheet cells with non-breaking spaces; partially-applied accounting formats; scientific/odd notation the normalizer doesn't handle.

Related errors


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