HKUDS/Vibe-Trading · error · ValueError
{text!r} uses a single comma and could be either {text.repla
Error message
{text!r} uses a single comma and could be either {text.replace(',', '')} (comma groups thousands) or {text.replace(',', '.')} (comma is the decimal separator); pass decimal_separator='.' or decimal_separator=',' to say which What it means
Raised (as ValueError from _to_plain_number) when a numeric cell contains exactly one comma and no dot, making the number ambiguous: '1,234' could be 1234 (thousands grouping) or 1.234 (decimal comma). The library refuses to guess because either interpretation yields a plausible but different number; the caller must disambiguate via decimal_separator.
Source
Thrown at agent/src/entities/ingest.py:168
ValueError: If the value uses a single comma whose role cannot be
determined -- ``"1,234"`` is 1234 in a US export and 1.234 in a
European one, and the data cannot say which.
"""
if decimal_separator is not None:
grouping = "," if decimal_separator == "." else "."
return text.replace(grouping, "").replace(decimal_separator, ".")
has_dot = "." in text
has_comma = "," in text
if has_dot and has_comma:
# The rightmost separator is the decimal one; the other groups digits.
if text.rindex(".") > text.rindex(","):
return text.replace(",", "")
return text.replace(".", "").replace(",", ".")
if has_comma:
if text.count(",") > 1:
return text.replace(",", "") # 1,234,567 cannot be a decimal comma
raise ValueError(
f"{text!r} uses a single comma and could be either "
f"{text.replace(',', '')} (comma groups thousands) or "
f"{text.replace(',', '.')} (comma is the decimal separator); pass "
"decimal_separator='.' or decimal_separator=',' to say which"
)
return text
def _parse_amount(
raw: str,
path: Path,
row_number: int,
decimal_separator: str | None = None,
) -> float:
"""Parse a numeric amount from a file field.
Handles currency symbols, digit grouping, and the accounting convention
where parentheses or a trailing minus denote a negative number, e.g.View on GitHub (pinned to 80ffdda44c)
Solutions
- Inspect the raw value cited in the message and determine whether the comma groups thousands or marks decimals
- Pass decimal_separator='.' if commas group thousands, or decimal_separator=',' if the comma is the decimal separator
- For per-file locales, load each file with its own decimal_separator rather than a global setting
- If the file mixes conventions, normalize the source data first
Example fix
# before
flows = load_cashflows('eu_export.csv')
# after
flows = load_cashflows('eu_export.csv', decimal_separator=',') Defensive patterns
Strategy: validation
Validate before calling
import re
def detect_ambiguous(cell: str) -> bool:
return cell.count(',') == 1 and '.' not in cell
ambiguous = [r for r in rows if detect_ambiguous(r['amount'])]
if ambiguous:
raise SystemExit('ambiguous decimals; choose decimal_separator explicitly') Type guard
def is_unambiguous_number(text: str) -> bool:
t = text.strip()
return not (t.count(',') == 1 and '.' not in t) Try / catch
try:
load_cashflows(p)
except CashFlowIngestError as e:
if 'could be either' in str(e):
load_cashflows(p, decimal_separator=decide_by_locale_of(p)) Prevention
- Always pass decimal_separator for non-ISO exports
- Standardize exports to one locale before ingestion
- Log the source system's locale alongside the file path
When it happens
Trigger: load_cashflows / _parse_amount encounters a cell like '1,234' or '12,5' and decimal_separator is None. Values with multiple commas ('1,234,567') or with both separators are resolved automatically; only the single-comma/no-dot case raises.
Common situations: European exports with decimal commas ('1234,5' with one digit after) that look like thousands groups; US exports with a single thousands comma ('1,234'); mixed-locale CSVs loaded without configuration.
Related errors
- {path} row {row_number}: amount {raw!r} is not usable: {exc}
- {path}: unknown column mapping {field_name!r}; mappable fiel
- {path}: mapped column {source_name!r} for field {field_name!
- {path} row {row_number}: amount is blank. A missing amount m
- {path} row {row_number}: date is blank
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/2d8783f014687f78.
Report an issue: GitHub.