MadsLorentzen/ai-job-search · error · ValueError
ambiguous comma separator
Error message
ambiguous comma separator
What it means
Raised when a string contains exactly one comma in the pattern digits,3-digits (e.g. '1,234'). This matches both US thousands ('1,234' = 1234) and European decimal ('1,234' = 1.234), so converting it either way risks a 1000x error; the function refuses rather than guess.
Source
Thrown at tools/convert_salary_excel.py:77
if isinstance(value, (int, float)):
return float(value)
if not isinstance(value, str):
raise ValueError("not numeric")
text = value.strip().replace("\u00a0", " ").replace(" ", "")
if not text:
raise ValueError("not numeric")
if "," in text and "." in text:
# The separator that appears last is the decimal separator: European
# "1.234,56" and US "1,234.56" are both unambiguous here, unlike the
# single-separator cases below.
if text.rfind(",") > text.rfind("."):
text = text.replace(".", "").replace(",", ".")
else:
text = text.replace(",", "")
elif "," in text:
if re.fullmatch(r"[+-]?\d+,\d{3}", text):
raise ValueError("ambiguous comma separator")
text = text.replace(",", ".")
elif "." in text:
if re.fullmatch(r"[+-]?\d+\.\d{3}", text):
raise ValueError("ambiguous dot separator")
return float(text)
def header_matches(header, patterns):
"""Return True when a header contains a meaningful pattern match.
Patterns match whole tokens; any pattern also listed in
``COMPOUND_PATTERNS`` may additionally match as a substring, to handle
languages that form compound words.
"""
h = header.lower().strip()
tokens = set(re.findall(r"[a-zæøåöäü0-9]+", h))
for p in patterns:View on GitHub (pinned to 79cd383e58)
Solutions
- Disambiguate the locale before parsing: if you know the sheet is European, rewrite the comma to a dot first ('1,234' -> '1.234'); if US, strip the comma
- Add more context, e.g. pass values with an explicit decimal part ('1,234.0' or '1,234,00' are unambiguous)
- Catch this ValueError in parse_sheet, log the raw cell, and resolve manually or via a locale parameter
Example fix
// before
num = parse_numeric_cell('1,234') # raises
// after
num = parse_numeric_cell('1,234'.replace(',', '') if locale == 'us' else '1,234'.replace(',', '.')) Defensive patterns
Strategy: try-catch
Validate before calling
import re
AMBIG = re.compile(r'[+-]?\d+,\d{3}$')
if isinstance(v, str) and AMBIG.fullmatch(v.strip()):
v = v.replace(',', '.' if locale == 'eu' else '') Type guard
def is_ambiguous_comma(v) -> bool:
return isinstance(v, str) and bool(re.fullmatch(r'[+-]?\d+,\d{3}', v.strip())) Try / catch
try:
num = parse_numeric_cell(v)
except ValueError as e:
if 'ambiguous comma' in str(e):
raise LocaleNeeded(v) # surface for manual/locale resolution
raise Prevention
- Know the sheet's locale before parsing and pre-normalize separators
- Export source data with explicit decimals so formats are unambiguous
- Catch the ambiguity error and resolve per-column with a locale flag
When it happens
Trigger: Passing a string like '1,234', '42,000', or '-9,999' that fullmatches r'[+-]?\d+,\d{3}'. Common when a sheet has US-formatted thousands without a decimal part, or a European decimal with exactly three fraction digits.
Common situations: Excel cells formatted with thousands separators exported as text ('1,234'), or a locale mismatch: a Danish/European sheet where '1,234' means 1.234 parsed with US assumptions. Any single-group thousands value with exactly 3 digits after the comma triggers it by design.
Related errors
AI-assisted analysis of MadsLorentzen/ai-job-search@79cd383e58 (2026-08-27).
Data as JSON: /api/errors/460264f381fc83d3.
Report an issue: GitHub.