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
- Look at the raw value in the message and the inner exc text; strip non-numeric decoration in the source or a preprocessing pass
- Fix malformed values such as double dots or stray characters at the source
- If values use a locale format, also pass decimal_separator appropriately
- 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
- Pre-clean amount cells: strip currency codes, symbols, NBSPs
- Pin decimal_separator for grouped formats
- Quarantine failing rows and alert rather than retrying unchanged
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
- {path}: mapped column {source_name!r} for field {field_name!
- {text!r} uses a single comma and could be either {text.repla
- {path} row {row_number}: amount is blank. A missing amount m
- str(exc)
- kind must be a string, got {type(value).__name__}
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/bc85f9b112dd5fbd.
Report an issue: GitHub.