MadsLorentzen/ai-job-search · error · ValueError
ambiguous dot separator
Error message
ambiguous dot separator
What it means
Raised when a string contains exactly one dot in the pattern digits.3-digits (e.g. '1.234'). This is ambiguous between a US decimal ('1.234' = 1.234) and a European thousands separator ('1.234' = 1234), so the function refuses to guess and raises rather than risking a 1000x misinterpretation.
Source
Thrown at tools/convert_salary_excel.py:81
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:
if p in tokens:
return True
if p in COMPOUND_PATTERNS and p in h:
return TrueView on GitHub (pinned to 79cd383e58)
Solutions
- Apply the correct locale transform first: European sheets -> remove the dot ('1.234' -> '1234'); US sheets with 3-decimal fractions -> keep as-is after confirming intent
- Normalize the source column to include a decimal comma/dot that disambiguates (e.g. '1.234,5' or '1,234.5')
- Catch the ValueError, log the raw cell and row, and resolve via a locale flag or manual review
Example fix
// before
num = parse_numeric_cell('55.000') # raises: 55000 or 55.0?
after
num = parse_numeric_cell('55.000'.replace('.', '')) # European sheet: 55000.0 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 '.') # eu: thousands sep Type guard
def is_ambiguous_dot(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 dot' in str(e):
raise LocaleNeeded(v)
raise Prevention
- For European sheets strip dots used as thousands separators beforehand
- Require source values to carry a disambiguating second separator
- Log ambiguous values and review the magnitude against expectations (a 1000x error is the risk)
When it happens
Trigger: Passing a string that fullmatches r'[+-]?\d+\.\d{3}' such as '1.234', '65.500', or '2.000'. Typical for European-formatted salaries ('2.000' meaning two thousand) or US decimals with exactly three fraction digits ('1.234').
Common situations: Danish/European Excel exports where '.' is the thousands separator ('55.000' kr), or US sheets with values like '0.125'. Without a second separator or locale hint the format cannot be inferred from the string alone.
Related errors
AI-assisted analysis of MadsLorentzen/ai-job-search@79cd383e58 (2026-08-27).
Data as JSON: /api/errors/3d7907b79ca6c64f.
Report an issue: GitHub.